Sunday, 5 July 2015

Public, private key generation in Java

In secure data communications, data is encrypted using a key, to provide confidentiality. There are two types of encryptions.

a.   Symmetric key encryption
b.   Public key encryption

a. Symmetric key Encryption
In Symmetric key encryption, data is encrypted and decrypted using same key, called secret key.

b. Public key encryption
It is also known as asymmetric key encryption. It uses two keys.
1.   Public key
2.   Private key
Every one knows public key, but only recipient knows private key. Suppose A wants to send a message M to B, then A encrypts M with B’s public key and send. At recipient end B decrypts message with his private key.

Each approach has it’s own advantages and disadvantages.

1.   Symmetric key encryption is easy to implement and faster. But main problem is both parties (sender and receiver) must exchange the key in secure way.
2.   Public key encryption works slow, but solves key exchange problem. In real world both the approaches combined to achieve more security and performance (See HTTPS).

In this post, I am going to explain how to generate public and private keys.

“java.security.KeyPairGenerator” class is used to generate public and private key pair. KeyPairGenerator class provides “getInstance” method, which takes algorithm name as argument and generate public and private key pairs specific to the algorithm supplied.

Following are the algorithms that java provides.
Algorithm
Description
Generates keypairs for the Diffie-Hellman KeyAgreement algorithm.
Generates keypairs for the Digital Signature Algorithm.
Generates keypairs for the RSA algorithm (Signature/Cipher).
Generates keypairs for the Elliptic Curve algorithm.

KeyPairGenerator class provides 3 forms of getInstance method.
getInstance(String algorithm)
getInstance(String algorithm, Provider provider)
getInstance(String algorithm, String provider)

First method returns KeyPairGenerator instance for specific algorithm mentioned in above table. Second and 3rd methods returns a new KeyPairGenerator object encapsulating the KeyPairGeneratorSpi implementation from the specified Provider object.

Once you got the instance of KeyPairGenerator, you can initialize KeyPairGenerator with specified parameter set. There are two ways to initialize KeyPairGenerator.

a. Algorithm-Independent initialization
Following methods are used to initialize KeyPairGenerator to initialize in Algorithm independent manner.

initialize(int keysize)
Initializes the key pair generator for a certain keysize using a default parameter set and the SecureRandom implementation of the highest-priority installed provider as the source of randomness.

initialize(int keysize, SecureRandom random)
Initializes the key pair generator for a certain keysize with the given source of randomness (and a default parameter set).
        
b. Algorithm-specific implementation
Following methods are used to initialize KeyPairGenerator to initialize in Algorithm dependent manner.

initialize(AlgorithmParameterSpec params)
Initializes the key pair generator using the specified parameter set and the SecureRandom implementation of the highest-priority installed provider as the source of randomness.

initialize(AlgorithmParameterSpec params, SecureRandom random)
Initializes the key pair generator with the given parameter set and source of randomness.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

public class PublicKeyUtil {

 public static KeyPair getKeyPair(String algorithm)
   throws NoSuchAlgorithmException {
  KeyPairGenerator keyPairGenerator = KeyPairGenerator
    .getInstance(algorithm);
  return keyPairGenerator.generateKeyPair();
 }

 public static PublicKey getPublicKey(KeyPair keyPair) {
  return keyPair.getPublic();
 }

 public static PrivateKey getPrivateKey(KeyPair keyPair) {
  return keyPair.getPrivate();
 }

 /**
  * Convert key to string.
  * 
  * @param key
  * 
  * @return String representation of key
  */
 public static String keyToString(Key key) {
  /* Get key in encoding format */
  byte encoded[] = key.getEncoded();

  /*
   * Encodes the specified byte array into a String using Base64 encoding
   * scheme
   */
  String encodedKey = Base64.getEncoder().encodeToString(encoded);

  return encodedKey;
 }

 /**
  * Save key to a file
  * 
  * @param key
  *            : key to save into file
  * @param fileName
  *            : File name to store
  */
 public static void saveKey(Key key, String fileName) {
  byte[] keyBytes = key.getEncoded();
  File keyFile = new File(fileName);
  FileOutputStream fOutStream = null;
  try {
   fOutStream = new FileOutputStream(keyFile);
   fOutStream.write(keyBytes);
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (fOutStream != null) {
    try {
     fOutStream.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }

}


import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;

import com.sample.PublicKeyUtil;

public class TestPublicKeyUtil {
 public static void main(String args[]) throws NoSuchAlgorithmException {
  KeyPair keyPair = PublicKeyUtil.getKeyPair("RSA");

  String publicKey = PublicKeyUtil.keyToString(PublicKeyUtil
    .getPublicKey(keyPair));
  String privateKey = PublicKeyUtil.keyToString(PublicKeyUtil
    .getPrivateKey(keyPair));

  System.out.println(publicKey);
  System.out.println(privateKey);
 }
}

Referred Articles

Related Articles


No comments:

Post a Comment