Google

Jun 21, 2014

Password based Encryption and decryption example in Java

Password-Based Encryption is can be accomplished using the PBEParameterSpec class. For example, if you are storing passwords for your database or RESTful web service connections in your properties file, they need to be encrypted and base64 encoded. You can't have clear text passwords lying around in properties files, URLs, or database tables.


Here is a sample CryptoHelper class that make use of PBEParameterSpec to perform password protected encryption and decryption.


import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.PBEKeySpec;


public class CryptoHelper {

    // Define the salt
    private static final byte[] SALT = {(byte)0x41, (byte)0x42, (byte)0x43, (byte)0x44,
                                        (byte)0x45, (byte)0x46, (byte)0x47, (byte)0x48}; //A to H

    // Iteration count
    private static final int COUNT          = 20;

    private static final String ALGORITHM   = "PBEWithMD5AndDES";

    // Create PBE parameter set
    private static PBEParameterSpec pbeParamSpec = new PBEParameterSpec(SALT, COUNT);


    /**
     * Not necessary at the moment as all methods are currently static.
     */
    protected CryptoHelper() {
    }


    /**
     * Encrypt a byte buffer using the given password.
     *
     * @param   data        The data to be encrypted.
     * @param   password    The password to be used.
     * @return  An encrypted byte array buffer.
     * @exception   CryptoException     Hmmm, we have a problem.
     * @see #decrypt(byte[],String)
     */
    public static byte[] encrypt(byte[] data, String password)  {
        return doCipher(Cipher.ENCRYPT_MODE, data, password);
    }


    /**
     * Decrypt a byte buffer using the given password.
     *
     * @param   data        The data to be decrypted.
     * @param   password    The password to be used.
     * @return  The original byte array buffer.
     * @exception   CryptoException     Hmmm, we have a problem.
     * @see #encrypt(byte[],String)
     */
    public static byte[] decrypt(byte[] data, String password)  {
        return doCipher(Cipher.DECRYPT_MODE, data, password);
    }


    /**
     * Performs password based encryption/decryption.
     *
     * @param   mode     Encrypt/Decrypt (Cipher.DECRYPT_MODE/Cipher.ENCRYPT_MODE)
     * @param   data     The data to be encrypted/decrypted.
     * @param   password The password to be used.
     * @return  The transformed byte buffer.
     * @exception   CryptoException     Hmmm, we have a problem.
     */
    private static byte[] doCipher(int mode, byte[] data, String password) {
        try {
            // First generate a SecretKey from the password given...
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);

            // Create PBE Cipher
            Cipher pbeCipher = Cipher.getInstance(ALGORITHM);

            // Initialize PBE Cipher with key and parameters
            pbeCipher.init(mode, pbeKey, pbeParamSpec);

            // Encrypt/Decrypt the data
            return pbeCipher.doFinal(data);
        } catch(Exception ex) {
            throw new RuntimeException("Cryptography Exception: " + ex);
        }
    }
}


The class with the method using the helper class.




//You can use any Base64 encoding library 
import org.eclipse.persistence.internal.oxm.conversion.Base64;

public class CryptographyTest {
 
 public static void main(String[] args) {
   String clearDatabasePassword = "passw0rd";
   String encryptionPasword = "changeit";
   
   byte[] encryptedDatabasePassword = CryptoHelper.encrypt(clearDatabasePassword.getBytes(), 
                                                                      encryptionPasword);
   System.out.println("Encrypted:" + new String(encryptedDatabasePassword));
   
   
   byte[] decryptedDatabasePasswor = CryptoHelper.decrypt(encryptedDatabasePassword, 
                                                                  encryptionPasword);
   System.out.println("Decrypted:" + new String(decryptedDatabasePasswor));
   
   //gives you the readable characters that can be used in your properties file
   System.out.println("Encrypted and Base64 encoded:" + new String(Base64.base64Encode(
                                                            encryptedDatabasePassword)));
     
 }
}



The output is

Encrypted:—¥3urÓ«É |Ã÷ Œ±)
Decrypted:passw0rd
Encrypted and Base64 encoded:l6UzdXLTq8mgfMP3FIyxKQ==


Now, you can have the password stored in common.properties file as shown below

myapp.db.password=l6UzdXLTq8mgfMP3FIyxKQ==

Base64 encoding helps you compactly transport binary data as readable characters.

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home