我在使用Python / M2Crypto验证DSA签名时遇到问题。使用标准的java.security.Signature类,并使用Sun的加密提供程序和SHA1withDSA算法名称,以Java语言生成签名。

这是一些shell输出:

>>> pk
<M2Crypto.DSA.DSA_pub instance at 0x20b6a28>
>>> sig = '302c02141c4bbb218215ebfec57288059ce814dc430d849502144dd0c581bf2213aff79d17eb37c939e120a97bd2'.decode('hex')
>>> data ='0501...9794'.decode('hex')
>>> pk.verify_asn1(sig, data)
------------------------------------------------------------
Traceback (most recent call last):
    ...
DSAError: wrong tag


签名值在我看来似乎还可以,它看起来像是正确的ASN.1编码序列,由两个整数组成(0x302c表示一个44字节的序列,而0x0214表示一个20字节的整数),这是DSA签名的标准编码。

由于甚至都没有记录DSA_pub.verify_asn1方法,因此我也尝试使用记录的DSA_pub.verify方法,但仍然没有雪茄:

>>> r = sig[4:24]
>>> s = sig[26:]
>>> md = sha1(data).digest()
>>> pk.verify(md, r, s)
------------------------------------------------------------
Traceback (most recent call last):
    ...
DSAError: encoding error


文档指出,所有参数都应为“字节字符串”,但verify方法以某种方式设法引发了编码错误。
我还尝试反转r和s,以检查潜在的字节序问题,但这没有帮助。

我究竟做错了什么?

最佳答案

在测试中找到解决方案:http://svn.osafoundation.org/m2crypto/trunk/tests/test_dsa.py

verify_asn1方法应按以下方式使用:

>>> pk.verify_asn1(sha1(data).digest(), sig)

10-07 12:34
查看更多