서명 역시 검증을 위해 전파될 필요가 있다. 즉, 직렬화가 필요하다.
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
0x80
보다 크거나 같은 경우 00
을 앞에 붙인 것을 사용해야 한다는 점이다.0x80 = 1000 0000
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)