Bouncy Castle DSA带有SHA1签名验证

时间:2014-05-19 10:09:01

标签: java cryptography digital-signature bouncycastle

我的项目正在使用来自某些第三方软件的某些数据集的签名验证。使用的签名算法是SHA1withDSA。当我使用SDK附带的标准SUN加密提供程序时,一切都很顺利。最近我转到了Bouncy Castle 1.50,之后转了一些以前的数据集(也就是SUN 提供者)经过验证,开始失败,其余的仍然经过验证确定。

我探索了两个提供商的源代码,结果发现SDK的默认提供商对错误形成的签名(虽然能够被恢复)有某种保护,而Bouncy Castle提供商没有它。查看 OpenJDK for Java 7(第336-344行)或 OpenJDK for Java 8(第265-273行):在某些情况下,他们已经做了一些签名修复。虽然org.bouncycastle.jcajce.provider.asymmetric.dsa.DSASigner#engineVerify没有这样做,但在org.bouncycastle.crypto.signers.DSASigner#verifySignature中明确指出数字必须是正数,否则验证会立即失败。

这是BC的一个错误,还是我错过了什么?要克服 这个,我已经分组了org.bouncycastle.crypto.signers.DSASigner和 在那里添加了相同的上述签名修复,然后插入此 在另一个签名算法中(通过子类化org.bouncycastle.jcajce.provider.asymmetric.dsa.DSASigner)。但也许我忽略了另一种方式,这个“问题”是众所周知的?请指教。

1 个答案:

答案 0 :(得分:2)

如果ASN.1整数的错误BER / DER编码 - 存储为签名大端,右对齐八位字节 - 确实是罪魁祸首那么Bouncy确实有一个错误。如果设置了编码的第一位,则应使用00值字节填充正值,否则它将表示负值。

Sun提供商错误地允许这些签名进行验证,而另一方当然会生成无效签名。请注意,可以让签名验证没有这个"修复"在Sun代码中:只需在将提供给验证函数之前调整编码。

唯一不可能的时候是将DSA验证作为通用签名验证方法从另一个库调用,而不是从可以在调用之前调整数据的应用程序调用。

另一方面,我认为你已经创造了一个优雅的解决方案。唯一的问题是,如果从符合JCA的框架验证提供商的签名,它可能无法运行。另一个可能的解决方法是在提供给Signature类之前对进行重新编码以进行验证。

请注意,我不知道这可能是一个安全问题;签名由R和S的值组成,只要您最终收到正确的值,它们的编码方式无关紧要。