/** * AES CBC decrypt. * * @param civ the cipher text, iv, and mac * @param secretKeys the AES & HMAC keys * @return The raw decrypted bytes * @throws GeneralSecurityException if MACs don't match or AES is not implemented */ public static byte[] decrypt(CipherTextIvMac civ, SecretKeys secretKeys) throws GeneralSecurityException { byte[] ivCipherConcat = CipherTextIvMac.ivCipherConcat(civ.getIv(), civ.getCipherText()); byte[] computedMac = generateMac(ivCipherConcat, secretKeys.getIntegrityKey()); if (constantTimeEq(computedMac, civ.getMac())) { Cipher aesCipherForDecryption = Cipher.getInstance(CIPHER_TRANSFORMATION); aesCipherForDecryption.init(Cipher.DECRYPT_MODE, secretKeys.getConfidentialityKey(), new IvParameterSpec(civ.getIv())); return aesCipherForDecryption.doFinal(civ.getCipherText()); } else { throw new GeneralSecurityException("MAC stored in civ does not match computed MAC."); } }