2016-01-10 104 views
0

我正在嘗試編寫一個驗證ECDSA簽名的python腳本,並且我正在嘗試這麼做的可怕時間。爲什麼python ECDSA不支持負數?

這是我使用的代碼:

public_key = ecdsa.VerifyingKey.from_string(pubkey, curve=ecdsa.SECP256k1) 
verified = public_key.verify_digest(signature, val, sigdecode=ecdsa.util.sigdecode_der) 

如果簽名[R小號是積極的,它工作得很好,但如果其中一方爲負,斷言錯誤引發。我檢查了ECDSA源代碼,我看到這一行:

nbytes = numberbytes[0] if isinstance(numberbytes[0], integer_types) else ord(numberbytes[0]) 
assert nbytes < 0x80 # can't support negative numbers yet 

https://github.com/warner/python-ecdsa/blob/master/ecdsa/der.py#L105

爲什麼會出現這種情況?這個圖書館不是「官方的」嗎?我有什麼替代方案?刪除該斷言行是否安全?

+0

您應該詢問軟件的作者:) –

+1

嘗試在r和s的值的開頭插入一個零('0x00')字節(例如,將'81AABB ...'更改爲0081AABB。 ..'),以確保數字被解釋爲正數(注意:這可能會很棘手,因爲您可能需要調整編碼簽名中的長度 - 取決於如何將「r」和「s」值傳遞給ecdsa圖書館)。 – vlp

回答

2

ECDSA本身不使用負數,所以我不希望它的Python實現支持負數。 ECDSA使用的數字類型在0和一些大的素數之間,他們服從模運算法則。

+0

那麼爲什麼我的openssl最終會返回負數或負數? – Jorky10

+1

@ Jorky10 - 這取決於標準。如果它們編碼爲ASN.1 ***'INTEGER' ***,那麼它們將永遠不會成爲負數,因爲會有一個前導00字節。如果它們是ASN.1 ***'OCTET_STRING' ***或一個字節字符串(即,當使用SHA1時,***'{r,s}'***對有40個字節時,64個字節用於**當使用SHA256等時,會出現'{r,s}'***對),那麼Python在其解析器或子例程中存在一個錯誤。 – jww

+0

我想這就是訣竅。謝謝你給我一條路! – Jorky10