简体   繁体   中英

AES 256 decryption - Is IV safe to share?

Following on this question and its answer, I am creating an application that given a password string, will convert a plaintext and store its ciphertext, the salt generated and the initialization vector in a text file.

In the following code :

public String decrypt(CryptGroup cp) throws Exception {
    String plaintext = null;
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec spec = new PBEKeySpec(password, cp.getSalt(), ITERATIONS, KEY_SIZE);
    SecretKey secretKey = factory.generateSecret(spec);
    SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(cp.getIv()));
    plaintext = new String(cipher.doFinal(cp.getCipher()), "UTF-8");

    return plaintext;
}

public CryptGroup encrypt(String plainText) throws Exception {
    byte[] salt = generateSalt();
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_SIZE);
    SecretKey secretKey = factory.generateSecret(spec);
    SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

    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(plainText.getBytes("UTF-8"));

    return new CryptGroup(ciphertext, salt, iv);
}

The CryptGroup object contains those 3 parameters (ciphertext, salt, iv : byte arrays for that matter).

Is it safe to store the initialization vector?

The answer in that question clearly states that the salt doesn't need to be secret, obviously the ciphertext can be also available, but what about the iv parameter?

Edit If it is not safe to share, is it possible to retrieve the original iv from the salt alone?

Yes, IV's can be public information. You can use a calculation as IV, as long as you never use the combination of key and IV twice. In other words, you should be able to share just the salt, as long as you change the salt for each encryption .

Furthermore, for CBC it is required that IV "looks like random" to an attacker, especially when used for the same key. So a usual scheme is to use some output of PBKDF2 as IV data. Those particular bits should of course not be used to create the key as well, but it is OK to split the output size.

This has some drawbacks as PBKDF2 will use many more rounds if you request more than 160 bits of information (for SHA1). So you may concatenate the output of PBKDF2 and a counter (0 for the key, 1 for the IV) and use eg SHA256 to generate a 128 bit key (the 16 leftmost bytes) and 128 bit IV (the 16 rightmost bytes).


Let's explore some variants to this scheme:

  • You could also use a different hash such as SHA-512 to create a larger output and split it to get a key and IV, but beware that such a function may not be available everywhere. Java 8 should have "PBKDF2WithHmacSHA512" though (for the SecretKeyFactory ).

  • You can also generate one PBKDF2 output and then use HKDF or HKDF-Expand to derive both a key and IV. Trouble is that HKDF / HKDF-Expand is not directly available from Java. Bouncy Castle does have that method though, because I send in an implementation of various KDF's.

  • Yet another way is to generate a new IV using SecureRandom , but in that case you need to store both the salt and IV. This might be useful if you need to encrypt multiple messages using the same key. In that case you can generate and store an IV for each separate message. This is a fine method if you are able to simply store 16 additional bytes.

  • In principle you could also use an all zero IV as long as you never reuse the same key (ie never reuse the same password/salt combination). However, in that case you might want to use AES-256 to avoid multi-target attacks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM