private static byte[] decrypt(EncryptedValue ev, char[] password) throws XiSecurityException {
AlgorithmIdentifier symmAlg = ev.getSymmAlg();
if (!PKCSObjectIdentifiers.id_PBES2.equals(symmAlg.getAlgorithm())) {
throw new XiSecurityException("unsupported symmAlg " + symmAlg.getAlgorithm().getId());
}
PBES2Parameters alg = PBES2Parameters.getInstance(symmAlg.getParameters());
PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters());
AlgorithmIdentifier encScheme = AlgorithmIdentifier.getInstance(alg.getEncryptionScheme());
try {
SecretKeyFactory keyFact =
SecretKeyFactory.getInstance(alg.getKeyDerivationFunc().getAlgorithm().getId());
SecretKey key;
int iterations = func.getIterationCount().intValue();
key = keyFact.generateSecret(new PBKDF2KeySpec(password, func.getSalt(), iterations,
KEYSIZE_PROVIDER.getKeySize(encScheme), func.getPrf()));
key = new SecretKeySpec(key.getEncoded(), "AES");
String cipherAlgOid = alg.getEncryptionScheme().getAlgorithm().getId();
Cipher cipher = Cipher.getInstance(cipherAlgOid);
ASN1Encodable encParams = alg.getEncryptionScheme().getParameters();
GCMParameters gcmParameters = GCMParameters.getInstance(encParams);
GCMParameterSpec gcmParamSpec =
new GCMParameterSpec(gcmParameters.getIcvLen() * 8, gcmParameters.getNonce());
cipher.init(Cipher.DECRYPT_MODE, key, gcmParamSpec);
return cipher.doFinal(ev.getEncValue().getOctets());
} catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException
| InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException
| InvalidAlgorithmParameterException ex) {
throw new XiSecurityException("Error while decrypting the EncryptedValue", ex);
}
}