11

I'm almost new to encryption.

I am trying to decrypt an array of bytes, and when I am providing the IV I am getting an exception : InvalidAlgorithmParameterException (no iv set when one expected).

Here's my code (iv is an array of 16 bytes which is not null and has the values used when encrypting) :

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, encriptionKey,new IvParameterSpec(iv));

If I don't specify the IV the cipher gets initialized ok :

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, encriptionKey);

Trying to find an answer I did find an implementation of JCEStreamCipher (here) which may not correspond to the version I am using but has some code that makes me thing I am not understanding it correctly.

Here's the code :

   if ((ivLength != 0) && !(param instanceof ParametersWithIV))
    {
        SecureRandom    ivRandom = random;

        if (ivRandom == null)
        {
            ivRandom = new SecureRandom();
        }

        if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
        {
            byte[]  iv = new byte[ivLength];

            ivRandom.nextBytes(iv);
            param = new ParametersWithIV(param, iv);
            ivParam = (ParametersWithIV)param;
        }
        else
        {
            throw new InvalidAlgorithmParameterException("no IV set when one expected");
        }
    }

Looks like I cannot provide an IV when decrypting, but it doesn't makes too much sense to me.

any help will be greatly appreciated.

thanks a lot, richard.

richardtz
  • 4,993
  • 2
  • 27
  • 38
  • Sorry, but I don't really understand your problem. May be you should better post the code you are using (more than two lines) instead of the one from JCEStreamCipher. – Robert Jul 16 '12 at 13:50
  • You say, "Looks like I cannot provide an IV when decrypting" Why not? The usual method is to prepend the IV to the front of the ciphertext and transmit them together. The receiver uses the first 16 bytes as the IV to decrypt the rest of the message. – rossum Jul 16 '12 at 14:19
  • That's how I'm doing it, but I got the exception when providing the IV to the decrypter, which was puzzling me. I had an error when creating the key (just posted the answer). – richardtz Jul 16 '12 at 14:24

1 Answers1

13

Solved.

I was using a wrong SecretKey, not the one you can create for AES.

Previously I had :

KeySpec spec = new PBEKeySpec(password.toCharArray(), encryptionKeySalt, 12345,256);
SecretKey encriptionKey = factory.generateSecret(spec);

which creates a JCEPBEKey.

I was missing :

Key encriptionKey = new SecretKeySpec(encriptionKey.getEncoded(), "AES"); 

which creates an appropiate key for AES.

richardtz
  • 4,993
  • 2
  • 27
  • 38
  • 1
    Excellent. This error was only happening on one older version of 4.0.3 device that was in the office, but not on the others. Now this works across platforms. – Jay Snayder May 16 '14 at 16:07