我正在尝试用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签名的原始数据(分离的签名?)?
答案 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");