@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
@Test(expected = IllegalArgumentException.class) public void bcGcmWithWrongLengthIv() throws Exception { new BouncyCastleAesGcmBytesEncryptor(password, salt, KeyGenerators.secureRandom(8)); } }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
@Test public void bcGcmWithSecureIvGeneratesDifferentMessages() throws Exception { BytesEncryptor bcEncryptor = new BouncyCastleAesGcmBytesEncryptor(password, salt); generatesDifferentCipherTexts(bcEncryptor); }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }
@Test public void bouncyCastleAesGcmWithSecureIvCompatible() throws Exception { CryptoAssumptions.assumeGCMJCE(); BytesEncryptor bcEncryptor = new BouncyCastleAesGcmBytesEncryptor(password, salt, KeyGenerators.secureRandom(16)); BytesEncryptor jceEncryptor = new AesBytesEncryptor(password, salt, KeyGenerators.secureRandom(16), CipherAlgorithm.GCM); testCompatibility(bcEncryptor, jceEncryptor); }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }
@Test public void bouncyCastleAesGcmWithPredictableIvEquvalent() throws Exception { CryptoAssumptions.assumeGCMJCE(); BytesEncryptor bcEncryptor = new BouncyCastleAesGcmBytesEncryptor(password, salt, new PredictableRandomBytesKeyGenerator(16)); BytesEncryptor jceEncryptor = new AesBytesEncryptor(password, salt, new PredictableRandomBytesKeyGenerator(16), CipherAlgorithm.GCM); testEquivalence(bcEncryptor, jceEncryptor); }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
@Bean TextEncryptor textEncryptor(@Value("${dm.security.cipher.password}") String password, @Value("${dm.security.cipher.salt}") String salt) { // on wrong configuration system will pass prop expressions '${prop}' as value, we need to detect this Assert.isTrue(StringUtils.hasText(password) && !password.startsWith("${"), "'dm.security.cipher.password' is invalid."); Assert.isTrue(StringUtils.hasText(salt) && !salt.startsWith("${"), "'dm.security.cipher.salt' is invalid."); //we use bouncycastle because standard java does not support keys bigger 128bits // but spring also does not provide any way to change key size // see also: https://github.com/spring-projects/spring-security/issues/2917 BytesEncryptor encryptor = new BouncyCastleAesGcmBytesEncryptor(password, salt); return new Base64Encryptor(encryptor); }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
/** * Recovers the data from a token, as a byte array * * @param token A token (key) obtained from this TokenService * @return The original data as a byte array * @throws NullPointerException if token is null * @throws IllegalStateException if data cannot be decrypted using this instance's secret * @throws ArrayIndexOutOfBoundsException if token is malformed */ protected byte[] decryptBytes(String token) { String[] parts = token.split("\\."); String salt = parts[0]; String encrypted = parts[1]; BytesEncryptor decryptor = new BouncyCastleAesGcmBytesEncryptor(secret, salt); return decryptor.decrypt(Base64.getUrlDecoder().decode(encrypted)); } }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
/** * Crypt a (non-null) byte array into a token * * @param data A byte array to turn into a token * @return A reversible token that contains the data */ protected String cryptBytes(byte[] data) { final String salt = KeyGenerators.string().generateKey(); BytesEncryptor encryptor = new BouncyCastleAesGcmBytesEncryptor(secret, salt); String encrypted = Base64.getUrlEncoder().encodeToString(encryptor.encrypt(data)); return salt + "." + encrypted; }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }