private static byte[] randomBytes(int length) throws GeneralSecurityException { fixPrng(); SecureRandom random = new SecureRandom(); byte[] b = new byte[length]; random.nextBytes(b); return b; }
/** * A function that generates random AES & HMAC keys and prints out exceptions but * doesn't throw them since none should be encountered. If they are * encountered, the return value is null. * * @return The AES & HMAC keys. * @throws GeneralSecurityException if AES is not implemented on this system, * or a suitable RNG is not available */ public static SecretKeys generateKey() throws GeneralSecurityException { fixPrng(); KeyGenerator keyGen = KeyGenerator.getInstance(CIPHER); // No need to provide a SecureRandom or set a seed since that will // happen automatically. keyGen.init(AES_KEY_LENGTH_BITS); SecretKey confidentialityKey = keyGen.generateKey(); //Now make the HMAC key byte[] integrityKeyBytes = randomBytes(HMAC_KEY_LENGTH_BITS / 8);//to get bytes SecretKey integrityKey = new SecretKeySpec(integrityKeyBytes, HMAC_ALGORITHM); return new SecretKeys(confidentialityKey, integrityKey); }
/** * A function that generates password-based AES & HMAC keys. It prints out exceptions but * doesn't throw them since none should be encountered. If they are * encountered, the return value is null. * * @param password The password to derive the keys from. * @return The AES & HMAC keys. * @throws GeneralSecurityException if AES is not implemented on this system, * or a suitable RNG is not available */ public static SecretKeys generateKeyFromPassword(String password, byte[] salt) throws GeneralSecurityException { fixPrng(); //Get enough random bytes for both the AES key and the HMAC key: KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, AES_KEY_LENGTH_BITS + HMAC_KEY_LENGTH_BITS); SecretKeyFactory keyFactory = SecretKeyFactory .getInstance(PBE_ALGORITHM); byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); // Split the random bytes into two parts: byte[] confidentialityKeyBytes = copyOfRange(keyBytes, 0, AES_KEY_LENGTH_BITS /8); byte[] integrityKeyBytes = copyOfRange(keyBytes, AES_KEY_LENGTH_BITS /8, AES_KEY_LENGTH_BITS /8 + HMAC_KEY_LENGTH_BITS /8); //Generate the AES key SecretKey confidentialityKey = new SecretKeySpec(confidentialityKeyBytes, CIPHER); //Generate the HMAC key SecretKey integrityKey = new SecretKeySpec(integrityKeyBytes, HMAC_ALGORITHM); return new SecretKeys(confidentialityKey, integrityKey); }