RSA Encryption in Java: Cross Platform Issues?
The Situation
I'm working with RSA encryption in Java. I'm trying to encrypt data on an HTC Saphire (32B) developer phone equipped with Cyanogenmod's Android 2.2 and then decrypt said data on a 64 bit server running Mandriva Linux 2010. I am using the same public key, private key pair on both machines, can correctly encrypt/decrypt data on the Android phone, can correctly encrypt/decrypt data on the Linux server, but I am unable to encrypt data on the phone and then decrypt it on the server. I get bad padding exceptions. I have confirmed that the data is being sent correctly by the phone and is being parsed correctly by the server. As such, I cannot figure out why decryption fails. Can anyone help me with this? Perhaps the RSA algorithm in Java has some underlying assumption about word size?
Further information:
- My encryption/decryption library is based on the guide found here.
- My encryption key is 2048 bits in length, but I see similar behaviour with different key sizes.
- I have packaged my RSA encryption/decryption code into a jar file. It was compiled through Eclipse on the server's machine.
- The program using the encryption library on the Android 开发者_如何学JAVAphone uses the above library. It too was built using Eclipse.
- The server program was built using Netbeans (as it was easier at the time to do so).
Other Questions
- Are there other free public-key encryption algorithms / libraries available for Java? Do they work cross-platform? What performance would one expect from them? Etc., etc. I've looked into this and haven't found much; perhaps I'm looking with the wrong keywords.
Phew! I think that's it. Thanks for your help in advance!
RSA encryption (or any encryption algorithm) should work regardless of environment. However, it is possible that certain systems make different assumptions about default padding and the mode of operation. Make sure that when you are performing encryption and decryption that you fully specify not only the algorithm, but also the mode of operation (CBC, etc) and the padding. If that doesn't work, I suggest posting your code from both the device and the server so we can examine it more closely.
Edit To address your question, in Java, when you get a cipher from the crypto package, you usually do so with the following code:
Cipher cipher;
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
The string provided to getInstance
instructs the runtime to get a cipher instance that will use the AES algorithm, the cipher block chaining mode of operation and the PKCS5 Padding. There are a number of supported algorithms and paddings. I would check out this document from Oracle for more information about encryption in Java.
To be more specific, the string you use to request a cipher is in the format
<algorithm>/<mode of operation>/<padding>
To make matters worse, despite Java providing a number of algorithms, modes of operation and paddings, not all of them will work together. You will need to read the documentation to find a configuration string that will work.
Perhaps you should do a checksum of the data and make sure it is exactly what you want to be passed into the encryption/decryption APIs.
精彩评论