Sunday 15 May 2011

Creating password-based string encryption with AES Algorithm

   Federal government organizations are now required to use FIPS 197, Advanced Encryption Standard (AES), which was approved for Federal government use in November 2001 to store encrypted data. In one of my assignment I was suppose to write a solution that can encrypt string based on some password/passphrase.

  There are a lot of examples for AES in the Internet (Google is a grate thing). The most correct and simple I found in this one Using the Java Cryptographic Extensions, which holds the following code

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
 
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
 
import sun.misc.BASE64Encoder;
 
/**
 * @author Joe Prasanna Kumar
 * This program provides the following cryptographic functionalities
 * 1. Encryption using AES
 * 2. Decryption using AES
 * 
 * High Level Algorithm :
 * 1. Generate a DES key (specify the Key size during this phase) 
 * 2. Create the Cipher 
 * 3. To Encrypt : Initialize the Cipher for Encryption
 * 4. To Decrypt : Initialize the Cipher for Decryption
 * 
 * 
 */
 
public class AES {
    public static void main(String[] args) {
        
        String strDataToEncrypt = new String();
        String strCipherText = new String();
        String strDecryptedText = new String();
        
        try{
        /**
         *  Step 1. Generate an AES key using KeyGenerator
         *          Initialize the keysize to 128 
         * 
         */
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();
         /**
         *  Step2. Create a Cipher by specifying the following parameters
         *             a. Algorithm name - here it is AES
         */
         Cipher aesCipher = Cipher.getInstance("AES");
         /**
         *  Step 3. Initialize the Cipher for Encryption 
         */
         aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);
         /**
         *  Step 4. Encrypt the Data
         *          1. Declare / Initialize the Data. Here the data is of type String
         *          2. Convert the Input Text to Bytes
         *          3. Encrypt the bytes using doFinal method 
         */
        strDataToEncrypt = "Hello World of Encryption using AES ";
        byte[] byteDataToEncrypt = strDataToEncrypt.getBytes();
        byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt); 
        strCipherText = new BASE64Encoder().encode(byteCipherText);
        System.out.println("Cipher Text generated using AES is " +strCipherText);
        
        /**
         *  Step 5. Decrypt the Data
         *          1. Initialize the Cipher for Decryption 
         *          2. Decrypt the cipher bytes using doFinal method 
         */
        aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());
        byte[] byteDecryptedText = aesCipher.doFinal(byteCipherText);
        strDecryptedText = new String(byteDecryptedText);
        System.out.println(" Decrypted Text message is " +strDecryptedText);
        }
        
        catch (NoSuchAlgorithmException noSuchAlgo)
        {
            System.out.println(" No Such Algorithm exists " + noSuchAlgo);
        }
        
            catch (NoSuchPaddingException noSuchPad)
            {
                System.out.println(" No Such Padding exists " + noSuchPad);
            }
        
                catch (InvalidKeyException invalidKey)
                {
                    System.out.println(" Invalid Key " + invalidKey);
                }
                
                catch (BadPaddingException badPadding)
                {
                    System.out.println(" Bad Padding " + badPadding);
                }
                
                catch (IllegalBlockSizeException illegalBlockSize)
                {
                    System.out.println(" Illegal Block Size " + illegalBlockSize);
                }
                
                catch (InvalidAlgorithmParameterException invalidParam)
                {
                    System.out.println(" Invalid Parameter " + invalidParam);
                }
    }
 
}

What I didn’t find, is how can I base my encryption on  the external password.


The solution is not to hard. Just replace



KeyGenerator keyGen = KeyGenerator.getInstance("AES");        
keyGen.init(128);        
SecretKey secretKey = keyGen.generateKey();

by



byte[] salt = { (byte)0xA9, 
            (byte)0x9B, 
            (byte)0xC8, 
            (byte)0x32, 
            (byte)0x56, 
            (byte)0x35, 
            (byte)0xE3, 
            (byte)0x03,
            (byte)0xA9, 
            (byte)0x9B, 
            (byte)0xC8, 
            (byte)0x32, 
            (byte)0x56, 
            (byte)0x35, 
            (byte)0xE3, 
            (byte)0x03};
PBEKeySpec password = new PBEKeySpec(passPhrase.toCharArray(), salt, 1000, 128);  
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");  
PBEKey key = (PBEKey) factory.generateSecret(password);  
SecretKey secretKey = new SecretKeySpec(key.getEncoded(), "AES");

 

  That did the job. Enjoy

No comments:

Post a Comment