throws JOSEException {
// Validate required JWE parts
if (encryptedKey == null) {
throw new JOSEException("The encrypted key must not be null");
}
if (iv == null) {
throw new JOSEException("The initialization vector (IV) must not be null");
}
if (authTag == null) {
throw new JOSEException("The authentication tag must not be null");
}
if (! critParamChecker.headerPasses(header)) {
throw new JOSEException("Unsupported critical header parameter");
}
// Derive the content encryption key
JWEAlgorithm alg = header.getAlgorithm();
SecretKey cek;
if (alg.equals(JWEAlgorithm.RSA1_5)) {
int keyLength = header.getEncryptionMethod().cekBitLength();
SecureRandom randomGen = getSecureRandom();
SecretKey randomCEK = AES.generateKey(keyLength, randomGen);
try {
cek = RSA1_5.decryptCEK(privateKey, encryptedKey.decode(), keyLength, keyEncryptionProvider);
} catch (Exception e) {
// Protect against MMA attack by generating random CEK on failure,
// see http://www.ietf.org/mail-archive/web/jose/current/msg01832.html
cek = randomCEK;
}
} else if (alg.equals(JWEAlgorithm.RSA_OAEP)) {
cek = RSA_OAEP.decryptCEK(privateKey, encryptedKey.decode(), keyEncryptionProvider);
} else if (alg.equals(JWEAlgorithm.RSA_OAEP_256)) {
cek = RSA_OAEP_256.decryptCEK(privateKey, encryptedKey.decode(), keyEncryptionProvider);
} else {
throw new JOSEException("Unsupported JWE algorithm, must be RSA1_5 or RSA_OAEP");
}
// Compose the AAD
byte[] aad = StringUtils.toByteArray(header.toBase64URL().toString());
// Decrypt the cipher text according to the JWE enc
EncryptionMethod enc = header.getEncryptionMethod();
byte[] plainText;
if (enc.equals(EncryptionMethod.A128CBC_HS256) ||
enc.equals(EncryptionMethod.A192CBC_HS384) ||
enc.equals(EncryptionMethod.A256CBC_HS512) ) {
plainText = AESCBC.decryptAuthenticated(
cek,
iv.decode(),
cipherText.decode(),
aad,
authTag.decode(),
contentEncryptionProvider,
macProvider);
} else if (enc.equals(EncryptionMethod.A128GCM) ||
enc.equals(EncryptionMethod.A192GCM) ||
enc.equals(EncryptionMethod.A256GCM) ) {
plainText = AESGCM.decrypt(
cek,
iv.decode(),
cipherText.decode(),
aad,
authTag.decode(),
contentEncryptionProvider);
} else if (enc.equals(EncryptionMethod.A128CBC_HS256_DEPRECATED) ||
enc.equals(EncryptionMethod.A256CBC_HS512_DEPRECATED) ) {
plainText = AESCBC.decryptWithConcatKDF(
header,
cek,
encryptedKey,
iv,
cipherText,
authTag,
contentEncryptionProvider,
macProvider);
} else {
throw new JOSEException("Unsupported encryption method, must be A128CBC_HS256, A192CBC_HS384, A256CBC_HS512, A128GCM, A192GCM or A256GCM");
}
// Apply decompression if requested
return DeflateHelper.applyDecompression(header, plainText);