Java RSA Encryption: An example

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.

22 thoughts on “Java RSA Encryption: An example

  1. 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.

  2. what is the data type of test used in statement String)test.getObject(myEncyptedMessage);
    Object or string

  3. 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.

  4. 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.

  5. 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.

  6. 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.


  7. 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.

  8. Hai Andreas,
    how to encrypt huge number of text using RSA with keypair generator?
    can i get source code for this?

  9. 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
    “ 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 ?

  10. 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 !

  11. 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!

  12. Thanks, liked the way you have explained it with every step.
    I have a small problem that i have small problem.
    I have to encrypt data in android and decrypt in java. It gave me java crypto bad padding exception.

  13. i am getting errors like
    “unreported exception IOException; must be caught or declared to be thrown
    SealedObject EncryptedMessage=new SealedObject(myMessage,c);”

    Wat shud i do to rectify.

    thanx :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>