rspec/rules/S3275/rule.adoc

51 lines
1.8 KiB
Plaintext
Raw Normal View History

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