Encrypting and Decrypting a message using Asymmetric Keys with Java, explained step-by-step with pictures

Introduction

In this article, we will review how to perform the encryption and decryption of a message using asymmetric keys with Java. Asymmetric-key cryptography refers to the process of using two separate keys when encrypting and decrypting a message. We call these two keys the PUBLIC KEY and the PRIVATE KEY. Asymmetric cryptography is also referred to as “public-key cryptography.”

A public key is a key that is provided to the outside world. Anyone who wants to send you a secret message will encrypt the message using your public key and then send the ciphertext to you.

A private key is a key that you do not share with anyone. The private and public keys are mathematically related. So if you receive a ciphertext that has been encrypted using your public key, only your private key has the ability to decrypt the ciphertext. You cannot both encrypt and decrypt the message with the public key, and the same goes for the private key.

For this demo, we will be using an RSA encryption scheme to perform the encryption and decryption operations. For a further explanation of RSA, click here.

Step 1: Come up with a message that we want to encrypt

The first step is obviously constructing a message that we want to encrypt. Our message will have to be an array of bytes because cipher algorithms require bytes in order to perform the encryption/decryption. So, let’s create our message…

byte[] message = "Hello, World!".getBytes();

Step 2: Create a KeyPairGenerator object

Next we need to create a KeyPairGenerator. This is an object that will allow us to generate both our public key and private key using a specific algorithm and key size. Let’s create a KeyPairGenerator that will be able to generate RSA keys…

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");

Step 3: Initialize the KeyPairGenerator with a certain key size

Now we have to tell our KeyPairGenerator how many bytes we want our keys to be. Since we are using an RSA algorithm, key sizes are generally one of the following: 512, 1024, 2048, or 4096 bits.

The more bytes our key has, the more secure the encryption. However, the more bytes our key has, the more computing power it will take to generate the key. So, you need to find a balance between the desired strength of your encryption and the speed of your program.

Let’s initialize our KeyPairGenerator to use 512 bits for our keys…

keyPairGenerator.initialize(512);

Step 4: Generate the keys

Now we can generate our KeyPair from our KeyPairGenerator object…

KeyPair keyPair = keyPairGenerator.generateKeyPair();

Step 5: Extract the keys

In order to use the keys individually, we have to grab the PrivateKey and PublicKey from the pair…

PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

Step 6: Create the Cipher object

The Cipher object will handle our encryption and decryption. The Cipher object needs to be given the following: a message in bytes, an encryption algorithm, and a public key.

Since we create a KeyPair using RSA, we need our Cipher object to use RSA as well, other wise Java will return an InvalidKeyException. We will be using RSA as the algorithm, ECB as the block cipher mode, and NoPadding. For more information about block cipher modes, click here. For more information on padding, click here.

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");

Step 7: Initialize the Cipher object

Now we need to tell our Cipher object two things: whether we want to encrypt or decrypt, and give it our public key.

A Cipher object performs both encryption and decryption of a message. Therefore, we need to specify that we are giving it cleartext and that we want it encrypted into cipher text.

cipher.init(Cipher.ENCRYPT_MODE, publicKey);

Step 8: Give the Cipher our message

Now we can give our clear text message to the Cipher object. We can do this with the .update() method…

cipher.update(message);

Step 9: Encrypt the message

We’ve provided the algorithm, the key, and the message to our Cipher object. Now we’re ready to tell Java to do the encryption. The Cipher object uses the .doFinal() method to perform the encryption…

byte[] ciphertext = cipher.doFinal();

Step 10: Print the ciphertext

Let’s print the ciphertext to make sure that the encryption worked…

System.out.println("message: " + new String(message, "UTF8"));
System.out.println("ciphertext: " + new String(ciphertext, "UTF8"));

Here’s the output…

message: Hello, World!
ciphertext: u♂????????{r??♥?→♀?p↕R6~??☻??5??d?↨n?nk?)∟*??>?????▬??:1

Now let’s decrypt our ciphertext so that we can see the clear message once again!

Step 11: Change the Cipher object’s mode and give it the private key

In order to decrypt our ciphertext, we have to make a few updates to our Cipher object.

First, let’s update our Cipher object to be in DECRYPT_MODE this time and give it the PrivateKey this time.

cipher.init(Cipher.DECRYPT_MODE, privateKey);

Step 12: Give the Cipher object our ciphertext

Let’s use the .update() method again to provide our Cipher object with our ciphertext this time…

cipher.update(ciphertext);

Step 13: Decrypt the ciphertext

Let’s use the .doFinal() method again to tell our Cipher object to decrypt our message and output the bytes to decrypted

byte[] decrypted = cipher.doFinal();

Lets make sure that our ciphertext was actually decrypted…

System.out.println("decrypted: " + new String(decrypted, "UTF8"));

Output…

decrypted: Hello, World!

Putting it all together…

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
public class Demo3 { public static void main(String[] args) throws Exception {

// Step 1: Come up with a message we want to encrypt
byte[] message = "Hello, World!".getBytes();
// Step 2: Create a KeyGenerator object
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
// Step 3: Initialize the KeyGenerator with a certain keysize
keyPairGenerator.initialize(512);
// Step 4: Generate the key pairs
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// Step 5: Extract the keys
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// Step 6: Create a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
// Step 7: Initialize the Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// Step 8: Give the Cipher our message
cipher.update(message);
// Step 9: Encrypt the message
byte[] ciphertext = cipher.doFinal();
// Step 10: Print the ciphertext
System.out.println("message: " + new String(message, "UTF8"));
System.out.println("ciphertext: " + new String(ciphertext, "UTF8"));
// Step 11: Change the Cipher object's mode
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// Step 12: Give the Cipher objectour ciphertext
cipher.update(ciphertext);
// Step 13: Decrypt the ciphertext
byte[] decrypted = cipher.doFinal();
System.out.println("decrypted: " + new String(decrypted, "UTF8")); }
}

Conclusion

There you have it! We’ve just encrypted and decrypted a message using an RSA encryption algorithm with 512-bit keys.

Hope this was helpful. Thanks for reading!

--

--

--

Staff Software Engineer at IBM — more about me at https://cernera.me/

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

PolyDoge Treats #2: Polysafu’s UNSAFU Bot

Looking forward to our V1 product spiritualagreement-Swap

How to Implement Authentication & Authorization with Auth0

{UPDATE} Absolute RC Buggy Race Off-Road Rally Championship Hack Free Resources Generator

{UPDATE} Tiny Pic Quiz Hack Free Resources Generator

tonaton.co.tz

Network Security Zoning

{UPDATE} Traffic Heavy Bike Race Hack Free Resources Generator

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Gregory Cernera

Gregory Cernera

Staff Software Engineer at IBM — more about me at https://cernera.me/

More from Medium

Encrypting and Decrypting a message using Symmetric Keys with Java, explained step-by-step with…

How to run multiple Java versions (like Java 8, 11 or latest) on Mac machine

How to create an executable jar library using JDK

How to enable replica set in embedded mongo with Spring Boot