Asymmetric Cryptography in Java

Security plays a significant role in our day to day life. So far software applications are concerned, security of data is required for authentication and for several validations. Normally while developing the applications, we use the concept of cryptography for password encryption and decryption. Some applications require more security, so they go for high end security system like trusted security certificates. The security mainly focuses on the integrity of the data at the several ends.

Technicalities For data security Java Cryptography provides a suitable framework to implement several kinds of cryptography. However there are basically two types of cryptography. Once is Symmetric Cryptography and Asymmetric Cryptography. When both the ends communicate the secured data with a common key for encryption and decryption, it is called the Symmetric Cryptography. In this case a shared key is used by both the parties to encrypt and decrypt the data. However there is a problem relating to exchange of key for symmetric cryptography. To overcome this problem java provides another approach for the cryptography called Asymmetric Cryptography. In case of Asymmetric cryptography, there will be two keys unlike one key in case of symmetric cryptography. One key is called Private key and other is called Public key. These two keys are generated together and can be used for encryption and decryption. In this case the Public key is used by anyone who wishes to communicate securely with the owner of the Private key. The Private key is used by the main owner and the owner gives the Public key so that they can decrypt the data. In this article I will give you the example on Asymmetric cryptography. You can find more tutorials and concept on Sun’s JCE(Java Cryptography Extension). In my next article, I will provide you the example on Symmetric cryptography.

Complete Example

This example is only meant for learning and not for any specific use. You can take the piece of code to test in your system to learn the above concept.

The following class is used to create the Public key and Private key. This class contains generic methods to generate the Public and Private key. If you run the testharness class, you will find the two files called “Public.key” and “Private.key”. Please go through the java docs mentioned in the methods.

Class Name : – KeyCreator.java

package com.dds.security;

import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

/**This class is used to generate the Private and Public key file.
 * The Public.key file and Private.key file will be generated in the
 * current directory.
 * @author Debadatta Mishra(PIKU)
 *
 */
public class KeyCreator
	{
		/**
		 * Object of type {@link PublicKey}
		 */
		private PublicKey publicKey = null;
		/**
		 * Object of type {@link PrivateKey}
		 */
		private PrivateKey privateKey = null;
		/**Default constructor.
		 * Here KeyPair object is initialized and
		 * thereby public key and private key objects
		 * are created.
		 * @throws Exception
		 */
		public KeyCreator() throws Exception
		{
			super();
			/*
			 * The following line is used to
			 * generate the Public and Private
			 * key.
			 */
			KeyPair keyPair = KeyPairGenerator
			.getInstance("RSA")
			.generateKeyPair();
			publicKey = keyPair.getPublic();
			privateKey = keyPair.getPrivate();
		}
		/**Method to return the {@link PublicKey}
		 * @return the {@link PublicKey}
		 */
		public PublicKey getPublicKey() {
			return publicKey;
		}
		/**Method to return the {@link PrivateKey}
		 * @return the {@link PrivateKey}
		 */
		public PrivateKey getPrivateKey() {
			return privateKey;
		}
		/**Method used to write the Public or Private
		 * key file.
		 * @param filename of type String indicating
		 * the name of Public or Private key
		 * @param contents of the key
		 */
		public void writeKey(String filename, byte[] contents)
		{
			try
			{
				FileOutputStream fos = new FileOutputStream(filename);
				fos.write(contents);
				fos.flush();
				fos.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}

The following class is used to read the “Public.key” and “Private.key” generated by the above program. If you are the owner you can have the “Private.key” file based upon which you have to encrypt the data and give your “Public.key” file to other end who wants to decrypt the data. In this following class, you can read both the “Public.key” and “Private.key” files.

Class Name:- KeyReader.java

package com.dds.security;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
 * This class is used to read the Private and Public key
 * files generated using the Java's Asysmmetric Security
 * system.
 * @author Debadatta Mishra(PIKU)
 *
 */
public class KeyReader
	{
		/**
		 * Object of type {@link KeyFactory}
		 */
		private KeyFactory keyFactory = null;
		/**
		 * Default constructor to initialize the
		 * keyFactory.
		 */
		public KeyReader()
		{
			super();
			try
			{
				keyFactory = KeyFactory.getInstance("RSA");
			}
			catch( Exception e )
			{
				e.printStackTrace();
			}
		}
		/**This method is used to read the bytes from the file.
		 * The file can be a Public key file or a Private key
		 * file. In this file, you have stored the security key,
		 * based upon which encryption and decryption can be
		 * performed.
		 * @param fileName of type String indicating the file name
		 * @return the bytes from the file
		 * @throws Exception
		 */
		private byte[] getKeyData( String fileName ) throws Exception
		{
			FileInputStream fis = new FileInputStream(fileName);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int b;
			try
			{
				while ((b = fis.read()) != -1)
				{
					baos.write(b);
				}
				fis.close();
				baos.flush();
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return baos.toByteArray();
		}
		/**This method is used to return the object of type
		 * {@link PrivateKey}. In this method you have to pass
		 * the file name of the Private.key file.
		 * @param filename of type String indicating the
		 * file name.
		 * @return the object of type {@link PrivateKey}
		 * @throws Exception
		 */
		public PrivateKey getPrivateKey( String filename ) throws Exception
		{
			PrivateKey privateKey = null;
			try
			{
				byte[] keydata = getKeyData(filename);
				PKCS8EncodedKeySpec encodedPrivateKey = new PKCS8EncodedKeySpec(keydata);
				privateKey = keyFactory.generatePrivate(encodedPrivateKey);
			}
			catch( Exception e )
			{
				e.printStackTrace();
			}
			return privateKey;
		}
		/**This method is used to return the object of type
		 * {@link PublicKey}. In this method you have to pass
		 * the file name of the Public.key file.
		 * @param filename of type String indicating the
		 * file name.
		 * @return the object of type {@link PublicKey}
		 * @throws Exception
		 */
		public PublicKey getPublicKey( String filename ) throws Exception
		{
			PublicKey publicKey = null;
			try
			{
				byte[] keydata = getKeyData(filename);
				X509EncodedKeySpec encodedPublicKey = new X509EncodedKeySpec(keydata);
				publicKey = keyFactory.generatePublic(encodedPublicKey);
			}
			catch( Exception e )
			{
				e.printStackTrace();
			}
			return publicKey;
		}
	}

The following class is a utility class which is used to encrypt and decrypt the data.

ClassName :- SecurityUtil.java

package com.dds.security;

import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;

/**This is a utility class to provide
 * encryption and decryption based upon
 * the key. The key can be your either
 * Public or Private .
 * @author Debadatta Mishra(PIKU)
 *
 */

public class SecurityUtil
	{
		/**
		 * Object of type {@link Cipher}
		 */
		private static Cipher cipher = null;
		/*
		 * The following static is used to
		 * initialize the Cipher object
		 */
		static
		{
			try
			{
				cipher = Cipher.getInstance("RSA");
			}
			catch( Exception e )
			{
				e.printStackTrace();
			}
		}
		
		/**Method used to encrypt the string and return as bytes.
		 * Here the input parameter will be your Private key.
		 * You have to encrypt the string using your private
		 * key at your end.
		 * @param messsageBytes , it is the bytes from the
		 * string to encrypt
		 * @param privateKey of type {@link PrivateKey}
		 * @return encrypted bytes
		 * @throws Exception
		 */
		
		public static byte[] getEncryptedBytes( byte[] messsageBytes , PrivateKey privateKey) throws Exception
		{
			byte[] encryptedBytes = null;
			cipher.init(Cipher.ENCRYPT_MODE , privateKey );
			encryptedBytes = cipher.doFinal(messsageBytes);
			return encryptedBytes;
		}
		
		/**Method used to decrypt the string and return as bytes.
		 * Here the input parameter will be your Public key.
		 * You have to decrypt the string using your Public
		 * key at the destination end.
		 * @param messsageBytes , it is the bytes from the
		 * string to encrypt
		 * @param publicKey of type {@link PublicKey}
		 * @return decrypted bytes
		 * @throws Exception
		 */
		
		public static byte[] getDecryptedBytes( byte[] messsageBytes , PublicKey publicKey)throws Exception
		{
			byte[] decryptedBytes = null;
			cipher.init(Cipher.DECRYPT_MODE , publicKey );
			decryptedBytes = cipher.doFinal( messsageBytes );
			return decryptedBytes;
		}
	}

The following is test harness class to test the functionality of the above program. Please go through the comments and java docs of the above and below programs.

Class Name :- SecurityTestHarness.java

package com.security.testharness;

import java.security.PrivateKey;
import java.security.PublicKey;
import com.dds.security.KeyCreator;
import com.dds.security.KeyReader;
import com.dds.security.SecurityUtil;
/**This is a test harness class used to
 * encrypt and decrypt the string based
 * upon the Public and Private key.
 * This class also helps to test how
 * Public and Private key can be created.
 * @author Debadatta Mishra(PIKU)
 *
 */
public class SecurityTestHarness
	{
		public static void main(String[] args)
		{
			try
			{
				/*
				 * The following lines will generate the
				 * PublicKey and PrivateKey files.
				 */
				KeyCreator keyCreator = new KeyCreator();
				PublicKey publicKey = keyCreator.getPublicKey();
				PrivateKey privateKey = keyCreator.getPrivateKey();
				/*
				 * Generate two files named Public.key and Private.key
				 */
				keyCreator.writeKey("Public.key", publicKey.getEncoded());
				keyCreator.writeKey("Private.key", privateKey.getEncoded());
				/*
				 * Get the public and private key
				 */
				KeyReader keyReader = new KeyReader();
				PublicKey publicKey2 = keyReader.getPublicKey("Public.key");
				System.out.println("Public Key----"+publicKey2);
				PrivateKey privateKey2 = keyReader.getPrivateKey("Private.key");
				System.out.println("Private Key----"+privateKey2);
				String str = "Hi, Hello World, Welcome to the World of Java";
				byte[] stringBytes = str.getBytes();
				byte[] encryptedBytes = SecurityUtil.getEncryptedBytes(
																	   stringBytes, privateKey2);
				String encryptedString = new String(encryptedBytes);
				System.out.println("EncryptedString----"+encryptedString);
				byte[] decryptedBytes = SecurityUtil.getDecryptedBytes(encryptedBytes, publicKey2);
				System.out.println("Decrypted String----"+new String(decryptedBytes));
			}
			catch( Exception e )
			{
				e.printStackTrace();
			}
		}
	}

To test the above programs, please create the appropriate package as mentioned in the program. You can also create your own package and modify the package name in the above programs. You can all the code in your favorable java editor.

Conclusion I hope that you will enjoy my article. If you find any problems or errors, please feel free to send me a mail in the address [email protected] . This article is only meant for those who are new to java development. This article does not bear any commercial significance. Please provide me the feedback about this article.

Debadatta Mishra(PIKU)

An aggressive java developer with a difference

Leave a Reply

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