Ecdsa
您如何使用python從簽名中找出r和s
這個連結似乎沒有加起來,有什麼建議嗎?
DER 編碼的 ECDSA 簽名的結構如下:
30
標識SEQUENCE
ASN1編碼中的a,後跟z
(序列)的長度。r
並且s
可以是 32 或 33 字節長,具體取決於 DER 編碼值的大小。r
並且s
總是以 開頭02
,它在 ASN1 中標識一個整數值。最後,tailing (ht
) 字節代表 hashtype為了解析簽名以提取兩個值,您應該檢查它們的長度,該長度始終為 1 字節長,並根據結果提取值。這是執行此操作的程式碼:
def parse_element(hex_str, offset, element_size): """ :param hex_str: string to parse the element from. :type hex_str: hex str :param offset: initial position of the object inside the hex_str. :type offset: int :param element_size: size of the element to extract. :type element_size: int :return: The extracted element from the provided string, and the updated offset after extracting it. :rtype tuple(str, int) """ return hex_str[offset:offset+element_size], offset+element_size def dissect_signature(hex_sig): """ Extracts the r, s and ht components from a Bitcoin ECDSA signature. :param hex_sig: Signature in hex format. :type hex_sig: hex str :return: r, s, t as a tuple. :rtype: tuple(str, str, str) """ offset = 0 # Check the sig contains at least the size and sequence marker assert len(hex_sig) > 4, "Wrong signature format." sequence, offset = parse_element(hex_sig, offset, 2) # Check sequence marker is correct assert sequence == '30', "Wrong sequence marker." signature_length, offset = parse_element(hex_sig, offset, 2) # Check the length of the remaining part matches the length of the signature + the length of the hashflag (1 byte) assert len(hex_sig[offset:])/2 == int(signature_length, 16) + 1, "Wrong length." # Get r marker, offset = parse_element(hex_sig, offset, 2) assert marker == '02', "Wrong r marker." len_r, offset = parse_element(hex_sig, offset, 2) len_r_int = int(len_r, 16) * 2 # Each byte represents 2 characters r, offset = parse_element(hex_sig, offset, len_r_int) # Get s marker, offset = parse_element(hex_sig, offset, 2) assert marker == '02', "Wrong s marker." len_s, offset = parse_element(hex_sig, offset, 2) len_s_int = int(len_s, 16) * 2 # Each byte represents 2 characters s, offset = parse_element(hex_sig, offset, len_s_int) # Get ht ht, offset = parse_element(hex_sig, offset, 2) assert offset == len(hex_sig), "Wrong parsing." return r, s, ht example_sig = None # insert_sig_here r, s, ht = dissect_signature(example_sig) print "r: %s\ns: %s\nht: %s\n" % (r, s, ht)