我正在开发一个数字签名java类,使用SHA1withRSA算法和256位证书。但我收到此错误:
Signature length not correct: got 344 but was expecting 256.
我正在使用 SunJSSE 提供程序(未实现 SHA256withRSA 算法),因为他使用 PKCS12 keystore 类型。我需要这个,因为这是一个批处理应用程序。
SAH1withRSA算法与256位证书不兼容吗?
最佳答案
首先,您不可能拥有 256 位 RSA 证书或 key 。当 RSA 于 1977 年发布时,256 位 RSA 并不安全,更不用说现在了。该异常(exception)表示它正在寻找 256 字节签名,即 2048 位,这意味着 key 和证书也是 2048 位,这是当前(自 2015 年以来)RSA 的标准和广泛使用的大小。
其次,是的SHA1withRSA 在技术上可与 2048 位 RSA key (和证书)配合使用,尽管它的安全性较低。 SHA1 最初的额定碰撞强度仅为 80 位,大约一年前已被破解(成本显着降低,约为 63 位) - 请参阅 https://shattered.io ——在很多情况下使得签名不安全,从而导致越来越多的系统、程序和用户拒绝SHA1签名。例如,从 8u144 开始(大约去年夏天)的所有 Oracle Java 软件包都默认配置了 java.security jdk.certpath.disabledAlgorithms
,以禁止在 TLS 中使用 SHA1 签名证书(包括SSL,但SSL也被破坏并默认被禁止)。 Java 目前并不禁止 SHA1 签名的其他用途,但可能会更改。您可能想要与之通信或互操作的很多东西,例如浏览器、网络服务器、电子邮件系统、存储库等,要么已经禁止 SHA1,要么可能会禁止。
但这不是必需的。您可以在一个程序中使用多个提供程序,特别是您可以使用 SunJSSE 的 KeyStore PKCS12,同时还可以使用 Signature SHA256withRSA(或其他 SHA2+RSA 变体) )来自 SunRsaSign。事实上,最简单的方法是根本不指定提供程序,而只让 KeyStore.getInstance()
和 Signature.getInstance()
(以及其他 JCA 接口(interface)类)自动找到正确的提供商。
最后,您的签名可能是 base64 编码的: ceil(256/3)*4=344。查看数据,看看它是否由 base64 字符组成,如果是,是哪一组字符。如果是base64,则将其解码为二进制(即Java中的byte[]
)并使用它。在Java8+中只需使用 java.util.Base64
它支持现在常见的两种变体:“MIME”变体和“URL-安全”(主要是 JSON)变体。在旧版 Java 中,您可以使用 javax.xml.bind.DatatypeConverter
来实现 MIME,或者使用任意数量的具有不同功能的第三方库。
关于java - 数字签名错误 - 签名长度不正确 : got 344 but was expecting 256,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52331138/