How do I properly use the "PBEWithHmacSHA512AndAES_256" algorithm?
// PROBLEM: If I pass "ivParamSpec", I get "java.security.InvalidAlgorithmParameterException: Wrong parameter type: PBE expected"
// Whereas if I pass pbeParamSpec, I get "java.security.InvalidAlgorithmParameterException: Missing parameter type: IV expected"
// What to do?
cipherDecrypt.init(
Cipher.DECRYPT_MODE,
key,
ivParamSpec
//pbeParamSpec
);
Use the AlgorithmParameters
from the encrypting Cipher
:
cipherDecrypt.init(
Cipher.DECRYPT_MODE,
key,
cipherEncrypt.getParameters()
);
If you want a cleaner way that doesn't involve cipherEncrypt
at the decrypting site, save the algorithm parameters as a byte and transmit them along with the key data:
byte[] algorithmParametersEncoded = cipherEncrypt.getParameters().getEncoded();
and reconstruct them at the decrypting site thus:
AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance(ALGORITHM);
algorithmParameters.init(algorithmParametersEncoded);
and use algorithmParameters
as the parameters
argument for Cipher.init()
above.
For those who jumps here from google. There is another way to specify IV for PBEwithHmacSHA512AndAES_256 cipher in java. IvParameterSpec can be added to PBEParameterSpec in constructor like this:
byte[] iv = ...;
byte[] salt = ...;
int iterations = 200000;
IvParameterSpec ivSpec = new IvParameterSpec(iv);
PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iterations, ivSpec);
Then such pbeSpec can be used to initialize the cipher:
cipher.init(
Cipher.DECRYPT_MODE,
key,
pbeSpec
);
Anyway the accepted answer provides a much cleaner solution - to serialize all cipher parameters at once with cipherEncrypt.getParameters().getEncoded(). The resulting byte array includes IV, salt and iteration count at once. It is completely ok to pass this data next to ciphered message at least for PBEwithHmacSHA512AndAES_256 algorithm