์„œ๋ช… ์—ญ์‹œ ๊ฒ€์ฆ์„ ์œ„ํ•ด ์ „ํŒŒ๋  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์ฆ‰, ์ง๋ ฌํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

DER(Distinguished Encoding Rules)

  • ์„œ๋ช…์— ๋Œ€ํ•ด ์•ž์—์„œ ๊ณต๋ถ€ํ–ˆ์„ ๋•Œ ํ•ต์‹ฌ์€ ์˜ ๊ฐ’์ด์—ˆ๋‹ค.
  • ์ด๋Š” private key๋ฅผ ๊ณต๊ฐœํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ๋‹ค์Œ์˜ ๋‘ ์ •๋ณด์˜ ์ž…์ฆ์„ ์œ„ํ•œ ๊ฐ’๋“ค์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • private key๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ์ •๋ณด
    • ๋‚ด๊ฐ€ ๋ณด๋‚ด๋Š” ์ •๋ณด๋ฅผ ๋‚ด๊ฐ€ ๋ณด๋ƒˆ๋‹ค๋ผ๋Š” ์ •๋ณด
  • ์˜ ๊ฒฝ์šฐ์—๋Š” ์••์ถ•ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๋‹ค.
  • ์ด์ „์—๋Š” ํƒ€์› ๊ณก์„ ์ด ๊ฐ€์ง€๋Š” ๋Œ€์นญ์„ฑ์„ ์ด์šฉํ–ˆ๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ์—๋Š” ํ•œ ๊ฐ’์—์„œ ๋‹ค๋ฅธ ๊ฐ’์„ ์œ ๋„ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์„œ๋ช…์„ ์ง๋ ฌํ™”ํ•˜๋Š” ํ‘œ์ค€์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ์‚ฌํ† ์‹œ๊ฐ€ ์‚ฌ์šฉํ–ˆ๋˜ DER์„ ์•Œ์•„๋ณผ ๊ฒƒ์ด๋‹ค.

์ •์˜ ๋ฐฉ๋ฒ•

3045022100ed81ff192e75a3fd2304004dcadb746fa5e24c5031ccfcf213
2060277457c98f02207a986d955c6e0cb35d446a89d3f56100f4d7f67801
ั31967743a9c8e10615bed

- marker - 30
- length of signature - 45
- marker for r value - 02
- r value lenth - 21
- r value (big Endian) - 00ed81ff192e75a3fd2304004dcadb746fa5e24c5031ccfcf213
2060277457c98f
- marker for s value - 02
- s value length - 20 
- s value (big Endian) - 7a986d955c6e0cb35d446a89d3f56100f4d7f67801
ั31967743a9c8e10615bed
  • ์ฃผ์˜ํ•  ์ ์€ r, s์˜ ๊ฐ’์„ ์‹ค์ œ๋กœ ๋„ฃ์„ ๋•Œ ์ฒซ๋ฒˆ์งธ ๋ฐ”์ดํŠธ๊ฐ€ 0x80๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฒฝ์šฐ 00์„ ์•ž์— ๋ถ™์ธ ๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.
    • ์ด๋ ‡๊ฒŒ ๋  ๊ฒฝ์šฐ r, s์˜ ๊ธธ์ด๋„ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๊ธธ์ด ํ‘œ์‹๋„ ๋ณ€๊ฒฝํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
    • ์œ„์— ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด r์€ 00์ด ๋ถ™์–ด์žˆ๊ณ , s๋Š” ์•„๋‹ˆ๋‹ค.
    • ๊ธธ์ด๋„ ๋‹ฌ๋ผ์ง„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์™œ ๊ตณ์ด ์ด๋ ‡๊ฒŒ ํ• ๊นŒ?
  • DER ํ˜•์‹์ด ์Œ์ˆซ๊ฐ’๋„ ์ˆ˜์šฉ๊ฐ€๋Šฅํ•œ ์ผ๋ฐ˜์  ํ˜•์‹์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋ถ€ํ˜ธ์žˆ๋Š” ์ด์ง„์ˆ˜์—์„œ ์ฒซ๋ฒˆ์งธ ๋น„ํŠธ๊ฐ€ 1์ธ ๊ฒƒ์€ ์Œ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
    • 0x80 = 1000 0000
  • ํƒ€์› ๊ณก์„  ์ „์ž ์„œ๋ช… (ECDSA)์—์„œ๋Š” ๋ชจ๋“  ๊ฐ’์„ ์–‘์ˆ˜๋กœ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์–‘์ˆ˜๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ!
    • ์—ฌ๊ธฐ์„œ ์„œ๋ช…์˜ ์ข…๋ฅ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
    • ๋˜ํ•œ ์Œ์ˆ˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋ช…๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๋ฌธ์ œ์ 

  • DER ํ˜•์‹์€ ์ผ๋ฐ˜์ ์ธ ํ˜•์‹์ด๊ธฐ ๋•Œ๋ฌธ์—, ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์ฑ„ํƒํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์„ ๋ชจ๋‘ ๋งŒ์กฑ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฉ์‹์ด ์ง€์ €๋ถ„ํ•˜๋‹ค.
  • ์›๋ž˜ r, s๊ฐ’์€ 256๋น„ํŠธ ์ •์ˆ˜์ด๊ณ , ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— 32๋ฐ”์ดํŠธ๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋Ÿฐ๋ฐ ์–‘์ˆ˜, ์Œ์ˆ˜์— ๋Œ€ํ•œ ๊ฐ’์„ ๋ณ€ํ™˜ํ•ด์•ผํ•˜๋Š” ๋กœ์ง์ด ๋“ค์–ด๊ฐ€๋ฉด์„œ 33๋ฐ”์ดํŠธ๋กœ ๋  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์‹ค์ œ๋กœ ์ตœ๋Œ€ DER ํ˜•์‹์€ 72๋ฐ”์ดํŠธ๊นŒ์ง€ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Ÿฐ ์  ๋•Œ๋ฌธ์— ๋น„ํŠธ์ฝ”์ธ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ๋Š” ์„œ๋ช… ๋ฐฉ์‹์„ ์Šˆ๋…ธ์–ด ๋ฐฉ์‹์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ๊ณ ์ • 64๋น„ํŠธ๋กœ ๊ฐ€์ž๋Š” ์˜๊ฒฌ๋„ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

๊ตฌํ˜„

 
class Signature:
 
    def __init__(self, r, s):
        self.r = r
        self.s = s
 
    def __repr__(self):
        return 'Signature({:x},{:x})'.format(self.r, self.s)
 
    def der(self):
        rbin = self.r.to_bytes(32, byteorder='big')
        # remove all null bytes at the beginning
        rbin = rbin.lstrip(b'\x00')
        # if rbin has a high bit, add a \x00
        if rbin[0] & 0x80:
            rbin = b'\x00' + rbin
        result = bytes([2, len(rbin)]) + rbin  # ์ •์ˆ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ bytes([])๋ฅผ ์‚ฌ์šฉํ•ด ๋ณ€ํ™˜
        sbin = self.s.to_bytes(32, byteorder='big')
        # remove all null bytes at the beginning
        sbin = sbin.lstrip(b'\x00')
        # if sbin has a high bit, add a \x00
        if sbin[0] & 0x80:
            sbin = b'\x00' + sbin
        result += bytes([2, len(sbin)]) + sbin
        return bytes([0x30, len(result)]) + result
 
    def parse(cls, signature_bin):
        s = BytesIO(signature_bin)
        compound = s.read(1)[0]
        if compound != 0x30:
            raise SyntaxError("Bad Signature")
        length = s.read(1)[0]
        if length + 2 != len(signature_bin):
            raise SyntaxError("Bad Signature Length")
        marker = s.read(1)[0]
        if marker != 0x02:
            raise SyntaxError("Bad Signature")
        rlength = s.read(1)[0]
        r = int.from_bytes(s.read(rlength), 'big')
        marker = s.read(1)[0]
        if marker != 0x02:
            raise SyntaxError("Bad Signature")
        slength = s.read(1)[0]
        s = int.from_bytes(s.read(slength), 'big')
        if len(signature_bin) != 6 + rlength + slength:
            raise SyntaxError("Signature too long")
        return cls(r, s)

์Šˆ๋…ธ๋ฅด ์„œ๋ช…

  • ์Šˆ๋…ธ๋ฅด์„œ๋ช…
  • ESCSA์™€ ์Šˆ๋…ธ๋ฅด ์„œ๋ช… ๋ชจ๋‘ ๊ฑฐ๋ž˜๋ฅผ ๋ณดํ˜ธํ•˜๊ณ  ๋ฉ”์‹œ์ง€ ์ง„์œ„๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋””์ง€ํ„ธ ์„œ๋ช… ๋ฐฉ์‹์ด๋‹ค.
  • ์Šˆ๋…ธ๋ฅด ์„œ๋ช…์€ ํšจ์œจ์„ฑ๊ณผ ํ™•์žฅ์„ฑ์—์„œ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฐฉ์‹.
  • ์Šˆ๋…ธ๋ฅด ์„œ๋ช…์€ ECDSA๋ณด๋‹ค ํšจ์œจ์ ์ด๊ณ  ๋น ๋ฅด๋‹ค.
  • ์—ฌ๋Ÿฌ ์„œ๋ช… (์—ฌ๋Ÿฌ๋ช…์ด ํ•œ๋ช…์—๊ฒŒ ๋ณด๋‚ด๋Š” ๊ฑฐ๋ž˜)์„ ํ•˜๋‚˜์˜ ์„œ๋ช…์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, ๊ฑฐ๋ž˜์˜ ํฌ๊ธฐ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ๋ธ”๋ก์— ๋” ๋งŽ์€ ๊ฑฐ๋ž˜๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข‹๋‹ค.
  • ECDSA์˜ ๊ฒฝ์šฐ ๊ฒ€์ฆ๊ณผ ์„œ๋ช…์„ ์œ„ํ•œ ๋‘๊ฐœ์˜ ํ‚ค(๊ฐœ์ธํ‚ค, ๊ณต๊ฐœํ‚ค)๋ฅผ ๊ฐ€์ ธ์•ผ ํ•˜์ง€๋งŒ
  • ์Šˆ๋…ธ๋ฅด ์„œ๋ช…์˜ ๊ฒฝ์šฐ ํ•˜๋‚˜์˜ ํ‚ค๋กœ ๋‘๊ฐœ์˜ ๋™์ž‘์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋” ๊ฐ„๋‹จํ•˜๋‹ค.
  • ์ด ๋ถ€๋ถ„์€ ๋‚˜์ค‘์— ๋–ผ์„œ ๊ณต๋ถ€ํ•˜๋„๋ก ํ•œ๋‹ค.

Reference