I had to use asymmetric keys in order to finish a university assignment, and to my amazement Sun could not publish any examples of using RSA keys in Java, because they were restricted by one of the stupidest laws in existence: US Cryptographic Export Laws. After playing with the API for a little while, I’ve managed to figure it out, eventually.
So I’m writing this post for those who want a simple example on how the key generation and encryption process works using RSA asymmetric keys.
Just for introduction, RSA is an algorithm for public-key cryptography. It was the first algorithm known to be suitable for signing as well as encryption, and one of the first great advances in public key cryptography. RSA is widely used in electronic commerce protocols, and is believed to be secure given sufficiently long keys and the use of up-to-date implementations. For more information on how RSA works, please take a look at the relevant Wikipedia article.
In order to start using RSA cryptography in Java, you will need to generate a key-pair: a public and a private key. The public key will be used to encrypt the data, and the private key will be used to decrypt the data. Without the private key, the data can not be decrypted, therefore it is suitable in cases where the clients want to send the server a shared-secret key or authentication information, in order to use for a session (kinda like SSL/TLS does). Java, starting version 1.5.0, provides a tool in the API for generating RSA key pairs.
The following code demonstrates how to use KeyPairGenerator to generate an RSA key-pair in Java:
// Get an instance of the RSA key generator
KeyPairGenerator kpg = KeyPairGenerator.getInstance(“RSA”);
// Generate the keys — might take sometime on slow computers
KeyPair myPair = kpg.generateKeyPair();
This will give you a KeyPair object, which holds two keys: a private and a public. In order to make use of these keys, you will need to create a Cipher object, which will be used in combination with SealedObject to encrypt the data that you are going to end over the network. Here’s how you do that:
// Get an instance of the Cipher for RSA encryption/decryption
Cipher c = Cipher.getInstance(“RSA”);
// Initiate the Cipher, telling it that it is going to Encrypt, giving it the public key
c.init(Cipher.ENCRYPT_MODE, myPair.getPublic());
After initializing the Cipher, we’re ready to encrypt the data. Since after encryption the resulting data will not make much sense if you see them “naked”, we have to encapsulate them in another Object. Java provides this, by the SealedObject class. SealedObjects are containers for encrypted objects, which encrypt and decrypt their contents with the help of a Cipher object.
The following example shows how to create and encrypt the contents of a SealedObject:
// Create a secret message
String myMessage = new String(“Secret Message”);
// Encrypt that message using a new SealedObject and the Cipher we created before
SealedObject myEncyptedMessage = new SealedObject( myMessage, c);
The resulting object can be sent over the network without fear, since it is encrypted. The only one who can decrypt and get the data, is the one who holds the private key. Normally, this should be the server. In order to decrypt the message, we’ll need to re-initialize the Cipher object, but this time with a different mode, decrypt, and use the private key instead of the public key.
This is how you do this in Java:
// Get an instance of the Cipher for RSA encryption/decryption
Cipher dec = Cipher.getInstance(“RSA”);
// Initiate the Cipher, telling it that it is going to Decrypt, giving it the private key
dec.init(Cipher.DECRYPT_MODE, myPair.getPrivate());
Now that the Cipher is ready to decrypt, we must tell the SealedObject to decrypt the held data.
// Tell the SealedObject we created before to decrypt the data and return it
String message = (String)test.getObject(myEncyptedMessage);
System.out.println(“foo = “+message);
Beware when using the getObject method, since it returns an instance of an Object (even if it is actually an instance of String), and not an instance of the Class that it was before encryption, so you’ll have to cast it to its prior form.
This is a small introductory example on how to generate RSA keys in Java and use them to encrypt objects. I’ll follow up with a tutorial on how to use asymmetric and symmetric keys in order to have secure network communication in Java.

March 22nd, 2008 at 10:36 pm
What is test ((String)test.getObject(myEncyptedMessage);) over here ?
March 25th, 2008 at 9:28 am
Object test is a SealedObject that got transfered to the server, using RMI.
When I upload the tutorial about asymmetric/symmetric keys it would employ RMI in order to be more clear how this technique works.
April 5th, 2008 at 9:54 pm
what is the data type of test used in statement String)test.getObject(myEncyptedMessage);
Object or string
April 6th, 2008 at 12:12 am
Object “test” in that line, is a SealedObject instance, which is identical to “myEncyptedMessage”. Supposedly you’d have myEncyptedMessage transported over RMI to the server.
April 8th, 2008 at 11:53 am
how about is i want to encrypt a file..i have read some article saying that RSA can’t encrypt file that are more than 117 bytes. can you explain more on sealobject being used with encrypting small file.
April 9th, 2008 at 12:42 am
Well, SealedObject is not designed to be used in encrypting files. It can be used to encrypt a String with the contents of a file, but bear in mind that the RSA Encryption has the size limitation you mentioned. You can always use a symmetric Cipher to encrypt objects longer than that.
If you want to encrypt a file however, Java provides CipherOutputStream for writing and CipherInputStream for reading encrypted data from Streams that can be either File or network streams.
CipherOutputStream class takes as parameters an OutputStream (with the destination file) and Cipher (like the above) and encrypts the output before writing to the file.
CipherInputStream can be used to read that file, providing that the same Cipher algorithm and key is used.
April 30th, 2008 at 10:38 pm
File, mpravo sigxaritira oti kalutero gia to mellon…
May 1st, 2008 at 1:19 pm
I used this approach for encrypting files:
http://www-users.york.ac.uk/~mal503/lore/pkencryption.htm
It uses RSA to encrypt an AES shared key which is then used to encrypt the files. Not sure if it’s the best way of doing things, but it works
December 4th, 2008 at 7:41 am
I believe there’s a mistake and the following line
String message = (String)test.getObject(myEncyptedMessage);
Should actually be
String message = (String) myEncryptedMessage.getObject(dec);
Thanks for the tutorial, it really helps out.
Cheers!
January 8th, 2009 at 8:29 pm
Thk for the example. I did not know about the US Cryptographic Export Laws.
2 notes :
1- There’s no mistake as Andreas explained, only some code portion missing (that was not needed).
2- String message = (String) myEncyptedMessage.getObject(dec); (without r) – or refactor the object.
April 4th, 2009 at 10:14 am
Hai Andreas,
how to encrypt huge number of text using RSA with keypair generator?
can i get source code for this?
October 5th, 2009 at 9:10 pm
i think there is still something missing in your code
i’ve tried to apply it but no matter what i do it get this
“java.security.InvalidKeyException: No installed provider supports this key: (null)”
i’ve tried to use the The Bouncy Castle Crypto APIs to get a provider
but still it did not work !
any ideas ?
October 6th, 2009 at 5:57 am
thats nice, except where do we magically get KeyPair to appear on the other computer?
November 30th, 2009 at 1:41 pm
CSStudent: by sending a pigeon ! Or by using symmetric key, to exchange the asymmetric key… It roughly depends of the network structure you re dealing with.
Thx for the small tuto, very useful !
March 16th, 2010 at 1:02 pm
So immensely helpful!
Thank you
June 8th, 2010 at 10:07 am
It worked as soon as I changed the code according to the comment made by Renato Back (I think you should post an example which combine it to one main-method). Very useful – other examples on the internet requires some 3rd party library – which I would rather avoid.
Good work!