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

时间:2016-08-13 02:45:31

标签: java encryption openssl rsa jce

我正在尝试用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代码计算inputData的SHA-256哈希值,然后签署哈希值并仅返回签名。

另一方面,

openssl似乎返回inputData以及签名。

我使用openssl rsautl -verify操作推断这一点。对Java签名数据运行此操作将返回ASN1编码数据,其中包含sha256对象。在openssl签名数据上运行此操作将返回实际输入数据。

有没有办法模仿openssl正在做什么 - 包括使用Java API签名的原始数据(分离的签名?)?

1 个答案:

答案 0 :(得分:0)

根据the answer here,签署时:
Java确实:
[哈希数据 - > ASN.1编码 - >垫 - > modexp]
openssl只做:
[Pad - > modexp]

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

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");