使用 Java 和 openssl rsautl -sign 的 RSA 签名之间的区别

Difference between RSA Sign with Java and openssl rsautl -sign

我正尝试在 Java 中为此 openssl 操作编写匹配代码: openssl rsautl -sign

到目前为止,我试过这个:

Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(privateKey, SecureRandom.getInstanceStrong());


ByteArrayInputStream bais = new ByteArrayInputStream(inputData);
byte[] sBuffer = new byte[1024];
int sBufferLen;
while ((sBufferLen = bais.read(sBuffer)) >= 0) {
        sig.update(sBuffer, 0, sBufferLen);
}
bais.close();

byte[] signature = sig.sign();

看起来 Java 代码计算了输入数据的 SHA-256 散列,然后对散列进行签名,return 仅对签名进行签名。

openssl,另一方面似乎 return inputData 以及签名。

我是使用 openssl rsautl -verify 操作推断的。 运行 对 Java 签名数据的此操作 returns 带有 sha256 对象的 ASN1 编码数据。 运行 此操作对 openssl 签名数据 returns 实际输入数据。

有什么方法可以使用 Java API 来模仿 openssl 正在做的事情 - 包括带有签名(分离签名?)的原始数据?

根据,签名时:
Java 做:
[哈希数据 -> ASN.1 编码 -> 填充 -> modexp]
openssl 只做:
[垫 -> modexp]

所以我不得不跳过 Java 中的前两步,以便它匹配 openssl rsautl -sign
为此,我查看了 RSASignature class 中的代码。

byte[] toBePadded = inputData.getBytes();
RSAPadding padding = RSAPadding.getInstance(1, 512, SecureRandom.getInstanceStrong());
byte[] toBeSigned = padding.pad(toBePadded);
byte[] opensslSignature = RSACore.rsa(toBeSigned, (RSAPrivateKey) privateKey, true);

编辑:使用 "NONEwithRSA" 签名类型更容易: Signature sig = Signature.getInstance("NONEwithRSA");