Thursday, February 7, 2013

Cryptography in Java

I spent an evening recently playing around with cryptography in Java. I had to look up something similar for work and then it piqued my interest so I had a bit of a play with it.

What I was looking to do was AES encrypt a file using a key derived from a passphrase. After some digging around it seems that the way to create a key is to use the PKCS #5 algorithm and hash the result. This can be done in Java with a key factory using the algorithm PBKDF2WithHmacSHA1:

    private static SecretKey generatePBKKey(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
        byte[] salt = new byte[16];
        rand.nextBytes(salt);
        KeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, 2, 128);
        SecretKey generatedKey = keyFactory.generateSecret(pbeKeySpec);

        SecretKey encKey = new SecretKeySpec(generatedKey.getEncoded(), "AES");

        return encKey;
    }


This key can then be used to initialise a AES Cipher which you can then encrypt the file with using a CipherOutputStream. Creating the AES Cipher was done using AES with ECB (Electronic Code Book) and PKCS5 padding.

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);


 I wasn't sure what block mode and padding to use and this seemed to be what most use.

The best doco I could find from Oracle was the Java 6 guide which ran through the main classes - http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html

 The full code of what I ended up with is over the jump.