数字签名错误 - 签名长度不正确:得到 344,但预期为 256

Rob*_*rto 2 java certificate digital-signature

我正在开发一个数字签名 java 类,使用 SHA1withRSA 算法和 256 位证书。但我收到此错误:

签名长度不正确:得到 344,但预期为 256。

我正在使用 SunJSSE 提供程序(未实现 SHA256withRSA 算法),因为他使用 PKCS12 密钥库类型。我需要这个,因为这是一个批处理应用程序。

SAH1withRSA算法与256位证书不兼容吗?

dav*_*085 8

首先,您不可能拥有 256 位 RSA 证书或密钥。当 RSA 于 1977 年发布时,256 位 RSA 并不安全,更不用说现在了。该例外表示它正在寻找 256字节签名,即 2048 位,这意味着密钥和证书也是 2048 位,这是当前(自 2015 年以来)RSA 的标准和广泛使用的大小。

其次,是的,SHA1withRSA 从技术上讲可以与 2048 位 RSA 密钥(和证书)一起使用,尽管它的安全性较低。SHA1 最初的评级仅为 80 位防碰撞强度,大约一年前已被破解(成本显着降低,约为 63 位) - 请参阅https://shattered.io - 使其对于许多签名来说不安全案例,从而导致越来越多的系统、程序和用户拒绝 SHA1 签名。例如,从 8u144 开始(大约去年夏天)的所有 Oracle Java 软件包都默认配置了 java.security,以禁止在 TLS 中jdk.certpath.disabledAlgorithms使用 SHA1 签名的证书(包括 SSL,但默认情况下 SSL 也被破坏并被禁止)。Java 目前并不禁止 SHA1 签名的其他用途,但可能会更改。您可能想要与之通信或互操作的很多东西,例如浏览器、网络服务器、电子邮件系统、存储库等,要么已经禁止 SHA1,要么可能会禁止。

但这没有必要。您可以在一个程序中使用多个提供程序,特别是您可以使用 SunJSSE 中的 KeyStore PKCS12,同时还可以使用 SunRsaSign 中的签名 SHA256withRSA(或其他 SHA2+RSA 变体)。事实上,最简单的方法是根本不指定提供程序,而只是让KeyStore.getInstance()Signature.getInstance()(以及其他 JCA 接口类)自动找到正确的提供程序。

最后,您的签名可能是 base64 编码的: ceil(256/3)*4=344。查看数据,看看它是否由 base64 字符组成,如果是,是哪一组字符。如果是base64,则将其解码为二进制(即byte[]Java)并使用它。在 Java8+ 中,只需使用java.util.Base64支持现在常见的两种变体:“MIME”变体和“URL 安全”(主要是 JSON)变体。在旧版 Java 中,您可以使用javax.xml.bind.DatatypeConverterMIME 或任意数量的具有不同功能的第三方库。