【发布时间】:2014-05-19 10:09:01
【问题描述】:
我的项目正在使用来自某些第三方软件的一些数据集的签名验证。使用的签名算法是SHA1withDSA。当我使用 SDK 附带的标准 SUN 加密提供程序时,一切正常。最近我切换到 Bouncy Castle 1.50,然后是之前的一些数据集(即使用 SUN
provider) 经受了验证,开始失败,而其余的仍然验证正常。
我研究了这两个提供者的源代码,结果发现 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)。但也许我忽略了另一种方式,这个“问题”是众所周知的?请指教。
【问题讨论】:
-
这是 BC 中的错误,还是我遗漏了什么 - 这不是 BC 中的错误。在您指向的代码中的所有 cmets 都提到值编码不正确之后,并且不接受不正确编码的信息几乎不能算作错误。恰恰相反,接受格式错误的签名或证书是非常值得怀疑的,因为它可能会带来安全威胁。
-
@mkl,您无法修复无法正确编码 ASN.1 整数的第三方软件,但 you can read and process such data。当然,决定是直接拒绝输入还是启用松散处理来修复其他软件中的常见错误是一个棘手的问题。
-
@OlegEstekhin 决定......是一个棘手的问题 - 是的。尤其是在与安全相关的错误输入“读取和处理”的情况下,输入可能是一个坏主意,因为它可能会破坏安全功能。话虽如此,我很清楚客户压力会迫使您“阅读和处理”,即使您看到安全方面被削弱了。
-
@mkl 我看到的问题是,一旦我以统一的方式(即通过 JCA)使用加密设施,那么切换提供者可能会伴随着细微的行为差异,但不会那么剧烈。我个人认为 JDK 的默认实现是一个经过深思熟虑的软件。如果他们没有放弃对长密钥的 SHA1withDSA1 的支持,我永远不会切换到 BC。但至少他们对此有一些合理的justification,关于成为遗产和那个。但是好吧,我想我可以接受我的解决方案。
标签: java cryptography digital-signature bouncycastle