Monday, September 1, 2014

Encrypting and Decrypting using Public Private Key in Java

Let's see how we can encrypt and decrypt information in Java using Public and Private Key. This tutorial is done in Java 8 so you may not find Base64 encoding API's in older version of Java. You can replace them with apache commons library. To generate public and private key follow the tutorial here. 

Let's assume we have public and private keystore sitting at E:/temp directory. First let's read the private key store and get the private key out of it. You need to know the password of keystore and key. I am assuming lalit123 for both.


// Private Keystore
FileInputStream privateKeyFile = new FileInputStream(
"E:/temp/lalit_private_keystore");

// Read the private keystore and get Private Key
KeyStore privateKeyStore = KeyStore.getInstance(KeyStore
.getDefaultType());
System.out.println("Type of private key: "
+ privateKeyStore.getDefaultType());
privateKeyStore.load(privateKeyFile, "lalit123".toCharArray());
PrivateKey privateKey = (PrivateKey)privateKeyStore.getKey("lalit_private", "lalit123".toCharArray());

Now let's get the public key also. Again let's assume the password is lalit456

// Public Keystore
FileInputStream publicKeyFile = new FileInputStream(
"E:/temp/lalit_public_keystore");

// Read the public keystore and get public key
KeyStore publicKeyStore = KeyStore.getInstance(KeyStore
.getDefaultType());
System.out.println("Type of public key: "
+ publicKeyStore.getDefaultType());
publicKeyStore.load(publicKeyFile, "lalit456".toCharArray());
Certificate publicCertificate = publicKeyStore
.getCertificate("lalit_public");
PublicKey publicKey = publicCertificate.getPublicKey();

Now let's first encrypt with private key and decrypt with public key

//Let's encrypt with private key and decrypt with public
// Encrypt with private key
String firstString = "Ishana";

Cipher privateEncryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
privateEncryptCipher.init(Cipher.ENCRYPT_MODE, privateKey);

byte[] encryptedFirstString = privateEncryptCipher
.doFinal(firstString.getBytes());
String encodedEncryptedFirstString = Base64.getEncoder()
.encodeToString(encryptedFirstString);
System.out.println("Encoded encrypted String for Ishana: "
+ encodedEncryptedFirstString);

// Decrypt with public key
// First decode the string
byte[] decodedEncryptedFirstString = Base64.getDecoder().decode(
encodedEncryptedFirstString);

Cipher publicDecryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
publicDecryptCipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] decryptedFirstStringByte = publicDecryptCipher
.doFinal(decodedEncryptedFirstString);
System.out.println("Decrypted String for Ishana: "
+ new String(decryptedFirstStringByte));

Let's reverse the things now

//Let's encrypt with public and decrypt with private
// Encrypt with public key
String secondString = "Ekagra";

Cipher publicEncryptCipher = Cipher.getInstance("RSA");
publicEncryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedSecondString = publicEncryptCipher
.doFinal(secondString.getBytes());
String encodedEncryptedSecondString = Base64.getEncoder()
.encodeToString(encryptedSecondString);
System.out.println("Encoded encrypted String for Ekagra: "
+ encodedEncryptedSecondString);

// Decrypt with private key
byte[] decodedEncryptedSecondString = Base64.getDecoder().decode(
encodedEncryptedSecondString.getBytes());
Cipher privateDecryptCipher = Cipher.getInstance("RSA");
privateDecryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedSecondStringByte = privateDecryptCipher
.doFinal(decodedEncryptedSecondString);
System.out.println("Decrypted String for Ekagra: "
+ new String(decryptedSecondStringByte));

Make sure to close the file handles to key store

privateKeyFile.close();
publicKeyFile.close();

I have not handled the exceptions above so you might want to handle them appropriately.

Code at GitHub
More on Java

3 comments: