M2Crypto:验证DSA签名

2 投票
1 回答
1735 浏览
提问于 2025-04-16 02:37

我在用Python/M2Crypto验证DSA签名时遇到了麻烦。这些签名是在Java中生成的,使用的是标准的java.security.Signature类,配合Sun的加密提供者和SHA1withDSA算法。

这是一些命令行输出:

>>> 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反过来,以检查是否有字节序的问题,但这也没有帮助。

我到底哪里出错了呢?

1 个回答

4

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

verify_asn1 方法应该这样使用:

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

撰写回答