Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my Java RSA encryption give me an Arithmetic Exception?

In .NET I have generated the following public key file:

<RSAKeyValue>
   <Modulus>xTSiS4+I/x9awUXcF66Ffw7tracsQfGCn6g6k/hGkLquHYMFTCYk4mOB5NwLwqczwvl8HkQfDShGcvrm47XHKUzA8iadWdA5n4toBECzRxiCWCHm1KEg59LUD3fxTG5ogGiNxDj9wSguCIzFdUxBYq5ot2J4iLgGu0qShml5vwk=</Modulus>
   <Exponent>AQAB</Exponent>
</RSAKeyValue>

.NET is happy to encrypt using it's normal methods.

I am trying to use this key to encode a string in Java. I am running into an Arithmetic Exception when I attempt to encrypt the string.

The following is the code I am using to encrypt:

byte[] modulusBytes = Base64.decode(this.getString(R.string.public_key_modulus));
byte[] exponentBytes = Base64.decode(this.getString(R.string.public_key_exponent));
BigInteger modulus = new BigInteger( modulusBytes );                
BigInteger exponent = new BigInteger( exponentBytes);

RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

byte[] cipherData = cipher.doFinal( new String("big kitty dancing").getBytes() );    

It is the final line in the code block that fails.

I have looked at numerous examples and this is the best I could come up with. If it is not obvious, the R.string.public_key_modulus is a copy/paste of the text in the Modulus element, same applies for exponent.

What did I do wrong?

like image 972
badMonkey Avatar asked Apr 22 '10 14:04

badMonkey


1 Answers

Try this:

BigInteger modulus = new BigInteger(1, modulusBytes );
BigInteger exponent = new BigInteger(1, exponentBytes);

Otherwise you end up with a negative modulus. The BigInteger(byte[]) constructor assumes a signed big-endian representation. The BigInteger(int, byte[]) constructor uses the provided sign bit (here "1" for "positive").

Also, be wary of String.getBytes(), it uses the platform "default charset" which depends on the configuration of the machine on which the application runs. It is better to specify an explicit charset (e.g. "UTF-8") if you want reproducible results.

like image 155
Thomas Pornin Avatar answered Oct 27 '22 01:10

Thomas Pornin