java - Java/BouncyCaSTLe 签名的 OpenSSL 等价物

标签 java openssl bouncycastle

我有一个软件做数字签名如下。

    MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
    Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    byte[] hash = md.digest("message".getBytes());
    byte[] signature = cipher.doFinal(hash);

我想用几行 batch/openssl 替换它,但无法重现此签名。基本上它是 SHA1 和 RSA 的组合,这还不错。我想知道为什么散列和加密是分开的。使用 openssl 执行此操作的两种方式都会产生不同的签名(忽略格式):

openssl dgst -sha1 -binary msg.txt > hash
openssl rsautl -sign -inkey priv.pem -in hash -hexdump

openssl dgst -sha1 -sign priv.pem -hex < msg.txt

所以我缺少一些东西......

更新:

感谢您的评论!当然,这段 Java 代码不是正确签名的方法,但验证代码不在我手中,我的目标是创建一个可以验证的签名。不过,我会提出改变整个事情的建议。

但我终于设法重现了签名。我自己不回答这个问题,因为我想要一个合适的 openssl 解决方案。所以这就是我得到的:

上面的 Java 代码填充!哈希码用零字节预填充,长度为 256!

最佳答案

Java 代码通过 SHA-1 哈希执行原始或教科书 RSA。这是不安全的,您应该在 Java 代码中使用 PKCS#1 v1.5 填充(用于签名生成)或 PSS。例如,PKCS#1 v1.5 是使用 Signature 类的 "SHA1withRSA" 算法字符串执行的。

虽然它不安全,但我尝试使用 -raw 参数复制 Java 代码的结果,但由于在 OpenSSL 代码中进行检查而失败了:

$ openssl rsautl -encrypt -raw -inkey priv.pem -in hash -hexdump
RSA operation error
3077884104:error:0406B07A:rsa routines:RSA_padding_add_none:data too small for key size:rsa_none.c:76:

所以 OpenSSL 不会让你犯这个错误。顺便说一下,我也尝试签名,结果相同。

默认情况下,OpenSSL 使用 PKCS#1 v1.5 填充(用于签名)进行签名生成,使用 PKCS#1 v1.5 填充(用于加密)进行加密。这将生成与 Java 代码中的原始签名不同的输出。

关于java - Java/BouncyCaSTLe 签名的 OpenSSL 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28765861/

相关文章:

python - Google API 和 cx_Freeze 无法正常工作

java - BouncycaSTLe 以编程方式安装提供程序

c# - 使用 Bouncy CaSTLe 在 C# 中加密和使用 AES(EAX 模式)在 Python 中解密的问题

java - 实时 Excel 更新

java - 多个文件存档的 ZIP 文件 servlet 响应已损坏

java - Phonegap 应用程序在运行 Android ICS 4.0 时抛出错误,但在 Android 2.3 及以下版本上运行良好

openssl - 如何使用 PKCS5_PBKDF2_HMAC_SHA1()

java - Kubernetes pod (Java) 以 137 TERMINATED 重新启动

openssl - 针对Linux arm-v5te-linux-gnueabi工具链的openssl的交叉编译

java - 使用 BouncyCaSTLe java API 进行 PGP 签名并使用 gpg4win 进行验证不起作用