devgianlu
devgianlu

Reputation: 1580

Implementing SHA1withRSA in Java

I'm trying to port a C++ program to Java, but not having much luck. The algorithm being used is RSASSA-PKCS1-v1_5. I know Java behaves differently from many other languages when it comes to cryptographic stuff.

This is known to be working:

bssl::UniquePtr<RSA> rsa(RSA_new());
rsa->n = BN_bin2bn(server_key, sizeof(server_key), nullptr);
rsa->e = BN_new();
BN_set_word(rsa->e, 65537);

std::uint8_t gs_hash[20];
SHA1(gs.data(), gs.size(), gs_hash);

if (1 != RSA_verify(NID_sha1, gs_hash, sizeof(gs_hash), gs_sig.data(), gs_sig.size(), rsa.get())) {
  // failed
}

My current implementation:

Security.addProvider(new BouncyCastleProvider());

byte[] serverKey = new byte[] {...};

KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey publicKey = factory.generatePublic(new RSAPublicKeySpec(new BigInteger(serverKey), BigInteger.valueOf(65537)));

MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] gs_hash = digest.digest(gs);

Signature sig = Signature.getInstance("SHA1withRSA/PSS", "BC");
sig.initVerify(publicKey);
sig.update(gs_hash);

if (sig.verify(gs_sig)) System.out.println("ALL GOOD");
else System.out.println("FAIL");

I've also tried using SHA1withRSA for the signature. gs and gs_sig are known and respectively 96 and 256 bytes long.

Test values:

serverKey: ace0460bffc230aff46bfec3bfbf863da191c6cc336c93a14fb3b01612acac6af180e7f614d9429dbe2e346643e362d2327a1a0d923baedd1402b18155056104d52c96a44c1ecc024ad4b20c001f17edc22fc43521c8f0cbaed2add72b0f9db3c5321a2afe59f35a0dac68f1fa621efb2c8d0cb7392d9247e3d7351a6dbd24c2ae255b88ffab73298a0bcccd0c58673189e8bd3480784a5fc96b899d956bfc86d74f33a6781796c9c32d0d32a5abcd0527e2f710a39613c42f99c027bfed049c3c275804b6b219f9c12f02e94863eca1b642a09d4825f8b39dd0e86af9484da1c2ba863042ea9db3086c190e48b39d66eb0006a25aeea11b13873cd719e655bd
gs: 4f2d7c6e76ccb6400ae1ff560d55a8084d98563ae03ac109d899fde735f6490935383cd1a97aa1fbff12e646f837194e9c6e57e1c5f956fcfde446a387c6be9a35c3225475f86df5a2c9b94626a2f90da3673af9861e33e8851a9a0ae20b9809
gs_signature: 35d1e685382f6d75bc5991f8ca1d252d70851c7bf66aa332bc6fc37bdb95da40c77c3cb452e6a70feda2bd6f63036d4b7a6d3f205789cf23a5777bcbd917a803ec2f3fb47fb6bdb911dd7d40dbe8425ad0d1905f1edb1bbc037ef4e259fa9c5dacdf9d58db8a18baf593d4e1c8055f51acffdaeeb10b4cee79f8b2421cfc28bdc9513859f76b101c965427334927207b575b9c29c581dfcc6fa4f135a1b04cfda4363e589f0510407faec4041b142b0ebbb9acd26dc2ed54fb28c38f560e05f8048c08c3574a4865f903192636987021eb72598ee822544026756ca294a150eb6642e65a860bac31fbba5ca0d800d030a52b515a7b8768def7de8e9f5dccdebe
gs_hash: 41aed19785bc5f4ffaa7eb30a29b1a39d52a225a

Upvotes: 0

Views: 981

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

There are two things wrong:

  1. You don't need to hash yourself when using "SHA1withRSA" (the signature will do the hashing for you, just feed it the data) and
  2. if you add "/PSS" then you're using a different scheme than PKCS#1 v1.5.

BigInteger(byte[]) will create a negative value if used with the modulus. You need to use BigInteger(1, byte[]) to make it a positive value. However, both Bouncy as the JCE should throw an exception on negative exponents, so I don't see how you make your code run anyway.

Upvotes: 1

Related Questions