bdeo bdeo - 1 year ago 188
Java Question

Difference between RSA Sign with Java and openssl rsautl -sign

I'm trying to write matching code in Java, for this openssl operation:

openssl rsautl -sign

So far, I tried this:

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

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

byte[] signature = sig.sign();

Looks like the Java code calculates the SHA-256 hash for the inputData, then signs the hash and returns the signature only.

openssl, on the other hand seems to return the inputData along with the signature.

I am inferring this using the
openssl rsautl -verify
operation. Running this operation on the Java signed data returns the ASN1 encoded data with a sha256 object in it. Running this operation on the openssl signed data returns the actual input data.

Is there any way to mimic what openssl is doing - including the original data with the signature (detached signature?) using Java APIs?

Answer Source

According to the answer here, while signing:
Java does:
[hash data -> ASN.1 encode -> Pad -> modexp]
openssl only does:
[Pad -> modexp]

So I had to skip the first two steps in Java, so that it matches openssl rsautl -sign
To do that I looked at the code in the 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);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download