java - 数字签名错误 - 签名长度不正确 : got 344 but was expecting 256

标签 java certificate digital-signature

我正在开发一个数字签名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/

相关文章:

ssl - Hyperledger Fabric-ca 的根证书

validation - 使用证书颁发机构的公钥进行 JWT 签名验证

c# - 使用 .pfx 证书封装、签名和创建 PKCS#7 DER 消息

Java 错误 MySql 泽西

java - 在 BoxLayout 中将 JLabel 与 JScrollPane 对齐

java - Authenticode、SPC 和 Java CodeSign 之间的区别?

java - 在 Python 和 Java/Scala 之间插入 RSA 签名时出现问题

java - FieldSet readString 方法不读取前导空格

java - 弹性 Spring jpa hibernate

ssl - 更新别名下的其中一个证书