SEC-1751: Applied patch to use zero-IV for queryable text encryption.

This commit is contained in:
Luke Taylor 2011-05-23 20:10:16 +01:00
parent 5a4aed238c
commit 21295a58e5
2 changed files with 28 additions and 10 deletions

View File

@ -46,13 +46,17 @@ final class AesBytesEncryptor implements BytesEncryptor {
private final BytesKeyGenerator ivGenerator;
public AesBytesEncryptor(String password, CharSequence salt) {
this(password, salt, null);
}
public AesBytesEncryptor(String password, CharSequence salt, BytesKeyGenerator ivGenerator) {
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), Hex.decode(salt), 1024, 256);
SecretKey secretKey = newSecretKey("PBKDF2WithHmacSHA1", keySpec);
this.secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
encryptor = newCipher(AES_ALGORITHM);
decryptor = newCipher(AES_ALGORITHM);
this.ivGenerator = ivGenerator;
this.ivGenerator = ivGenerator != null ? ivGenerator : NULL_IV_GENERATOR;
}
public byte[] encrypt(byte[] bytes) {
@ -60,27 +64,41 @@ final class AesBytesEncryptor implements BytesEncryptor {
byte[] iv = ivGenerator.generateKey();
initCipher(encryptor, Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
byte[] encrypted = doFinal(encryptor, bytes);
return concatenate(iv, encrypted);
return ivGenerator != NULL_IV_GENERATOR ? concatenate(iv, encrypted) : encrypted;
}
}
public byte[] decrypt(byte[] encryptedBytes) {
synchronized (decryptor) {
byte[] iv = ivPart(encryptedBytes);
byte[] iv = iv(encryptedBytes);
initCipher(decryptor, Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
return doFinal(decryptor, cipherPart(encryptedBytes, iv));
return doFinal(decryptor, ivGenerator != NULL_IV_GENERATOR ? encrypted(encryptedBytes, iv.length) : encryptedBytes);
}
}
// internal helpers
private byte[] ivPart(byte[] encrypted) {
return subArray(encrypted, 0, ivGenerator.getKeyLength());
private byte[] iv(byte[] encrypted) {
return ivGenerator != NULL_IV_GENERATOR ? subArray(encrypted, 0, ivGenerator.getKeyLength()) : NULL_IV_GENERATOR.generateKey();
}
private byte[] cipherPart(byte[] encrypted, byte[] iv) {
return subArray(encrypted, iv.length, encrypted.length);
private byte[] encrypted(byte[] encryptedBytes, int ivLength) {
return subArray(encryptedBytes, ivLength, encryptedBytes.length);
}
private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final BytesKeyGenerator NULL_IV_GENERATOR = new BytesKeyGenerator() {
private final byte[] VALUE = new byte[16];
public int getKeyLength() {
return VALUE.length;
}
public byte[] generateKey() {
return VALUE;
}
};
}

View File

@ -52,7 +52,7 @@ public class Encryptors {
/**
* Creates an encryptor for queryable text strings that uses standard password-based encryption.
* Uses a shared, or constant 16 byte initialization vector so encrypting the same data results in the same encryption result.
* Uses a 16-byte all-zero initialization vector so encrypting the same data results in the same encryption result.
* This is done to allow encrypted data to be queried against.
* Encrypted text is hex-encoded.
*
@ -60,7 +60,7 @@ public class Encryptors {
* @param salt a hex-encoded, random, site-global salt value to use to generate the secret key
*/
public static TextEncryptor queryableText(CharSequence password, CharSequence salt) {
return new HexEncodingTextEncryptor(new AesBytesEncryptor(password.toString(), salt, KeyGenerators.shared(16)));
return new HexEncodingTextEncryptor(new AesBytesEncryptor(password.toString(), salt));
}
/**