Java 256-bit AES Password-Based Encryption?

I need to implement 256 bit AES encryption, but all the examples I have found online use a “KeyGenerator” to generate a 256 bit key, but I would like to use my own passkey. How can I create my own key?

Generating your own key from a byte array is easy:

 

byte[] raw = ...; // 32 bytes in size for a 256 bit key

Key skey = new javax.crypto.spec.SecretKeySpec(raw, "AES");

But creating a 256-bit key isn't enough. If the key generator cannot generate 256-bit keys for you, then the Cipher class probably doesn't support AES 256-bit either. You say you have the unlimited jurisdiction patch installed, so the AES-256 cipher should be supported (but then 256-bit keys should be too, so this might be a configuration problem).

 

Cipher cipher = Cipher.getInstance("AES");

cipher.init(Cipher.ENCRYPT_MODE, skey);

byte[] encrypted = cipher.doFinal(plainText.getBytes());

A workaround for lack of AES-256 support is to take some freely available implementation of AES-256, and use it as a custom provider. This involves creating your own Provider subclass and using it with Cipher.getInstance(String, Provider). But this can be an involved process.

Share the password (a char[]) and salt (a byte[]—8 bytes selected by a SecureRandom makes a good salt—which doesn’t need to be kept secret) with the recipient out-of-band. Then to derive a good key from this information (in Java 6):

/* Derive the key, given password and salt. */

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);

SecretKey tmp = factory.generateSecret(spec);

SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

/* Encrypt the message. */

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, secret);

AlgorithmParameters params = cipher.getParameters();

byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();

byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));

Now send the ciphertext and the iv to the recipient. The recipient generates a SecretKey in exactly the same way, using the same salt and password. Then initialize the cipher with the key and the initialization vector.