When CBC (Cypher Block Chaining) is used for encryption, the IV (Initialization Vector) must be random an unpredictable. Otherwise it exposes the encrypted value to crypto-analysis attacks like "Chosen-Plaintext Attacks".


An IV should be used in one and only one encryption cycle because its purpose is to ensure that a different cyphertext value results each time a given plain text value is encrypted.


== Noncompliant Code Example

----
public String cbcEncrypt(String strKey, String plainText) {

  String strIV = "7cVgr5cbdCZVw5WY";
  IvParameterSpec ivSpec = new IvParameterSpec(strIV.getBytes("UTF-8"));
  SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");

  /* Ciphering */
  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
  cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);  // Noncompliant
  byte[] encryptedBytes = cipher.doFinal(plaintText.getBytes("UTF-8"));
  return DatatypeConverter.printBase64Binary(ivBytes) + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
}
----


== Compliant Solution

----
private SecureRandom random = new SecureRandom();

public void cbcEncrypt(String strKey, String plainText) {

  byte ivBytes[] = new byte[16];
  random.nextBytes(ivBytes);
  IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
  SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");

  /* Ciphering */
  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
  cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec); 
  byte[] encryptedBytes = cipher.doFinal(plaintText.getBytes("UTF-8"));
  return DatatypeConverter.printBase64Binary(ivBytes) + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
}
----


== See

* https://cwe.mitre.org/data/definitions/329.html[MITRE, CWE-329] - Not Using a Random IV with CBC Mode
* OWASP Top 10 2017 Category A6 - Security Misconfiguration

