0

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 = bais.read(sBuffer)) >= 0) {
        sig.update(sBuffer, 0, sBufferLen);
}
bais.close();

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?

bdeo
  • 113
  • 1
  • 10
  • [Why are the RSA-SHA256 signatures I generate with OpenSSL and Java different?](http://stackoverflow.com/q/13419201), [Multiple OpenSSL RSA signing methods produce different results](http://stackoverflow.com/a/38768455/608639), [Signing/verification between Java and the OpenSSL](http://crypto.stackexchange.com/q/30682), [(Java) Duplicating OpenSSL rsautl (creating RSA signatures)](https://www.example-code.com/java/rsa_openssl_rsautl_sign.asp), etc. – jww Aug 13 '16 at 03:30
  • Thanks @jww The answer at [Multiple OpenSSL RSA signing methods produce different results](http://stackoverflow.com/a/38768455/608639) was most useful. – bdeo Aug 15 '16 at 18:56

1 Answers1

1

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

Edit: Easier to just use "NONEwithRSA" signature type: Signature sig = Signature.getInstance("NONEwithRSA");

bdeo
  • 113
  • 1
  • 10