package com.example.crypto.artifacts; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.GCMParameterSpec; import java.security.*; import java.util.Base64; import java.util.random.*; import java.util.Properties; import java.util.Random; import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; public class Test { public static SecretKey generateAESKey()throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); return keyGen.generateKey(); } private static byte[] getRandomWrapper1()throws Exception { byte[] val = new byte[16]; new SecureRandom().nextBytes(val); return val; } private static byte[] getRandomWrapper2A()throws Exception { byte[] val; val = getRandomWrapper1(); funcA1(val); return val; } private static byte[] getRandomWrapper2b()throws Exception { byte[] val; val = getRandomWrapper1(); return val; } private static void funcA1(byte[] iv)throws Exception { IvParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey key = generateAESKey(); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // BAD: Reuse of `iv` in funcB1 byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); } private static void funcB1()throws Exception { byte[] iv = getRandomWrapper2A(); IvParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey key = generateAESKey(); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // BAD: Reuse of `iv` in funcA1 byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); } private static void funcA2()throws Exception { byte[] iv = getRandomWrapper2b(); IvParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey key = generateAESKey(); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // GOOD byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); } private static void funcB2()throws Exception { byte[] iv = getRandomWrapper2b(); IvParameterSpec ivSpec = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey key = generateAESKey(); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); // GOOD byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); } private static void funcA3() throws Exception { byte[] iv = getRandomWrapper2b(); IvParameterSpec ivSpec1 = new IvParameterSpec(iv); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey key1 = generateAESKey(); cipher.init(Cipher.ENCRYPT_MODE, key1, ivSpec1); // BAD: reuse of `iv` below byte[] ciphertext = cipher.doFinal("Simple Test Data".getBytes()); IvParameterSpec ivSpec2 = new IvParameterSpec(iv); Cipher cipher2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey key2 = generateAESKey(); cipher2.init(Cipher.ENCRYPT_MODE, key2, ivSpec2); // BAD: Reuse of `iv` above byte[] ciphertext2 = cipher2.doFinal("Simple Test Data".getBytes()); } public static void main(String[] args) { try{ funcA2(); funcB1(); funcB2(); } catch(Exception e) { e.printStackTrace(); } } }