AES 256 bit encryption - java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long

醉酒当歌 提交于 2019-12-20 15:32:09

问题


Below is my encryption logic. Although my IV is 16bytes long, I still get an error with invalid IV length. Would appreciate any help

@Override
public String encrypt(String dataToEncrypt, String IV) throws Exception{
    if(encryptionKey.length() < 10){
        encryptionKey = generateEncryptionKey().toString();
    }
    System.out.println("number of IV bytes is "+IV.length()+" "+IV);
    Cipher cipher = Cipher.getInstance(encrpytionAlgo);
    SecretKey key = new SecretKeySpec(encryptionKey.getBytes(Charset.forName("UTF-8")), "AES");
    cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes(Charset.forName("UTF-8"))));
    byte[] encryptedTextBytes = cipher.doFinal(dataToEncrypt.getBytes(Charset.forName("UTF-8")));
    return new Base64().encodeAsString(encryptedTextBytes);
}

IV and Key generation logic

 @Override
public String generateRandomIV(){
        Random random = new SecureRandom();
        byte[] iv = new byte[16];
        random.nextBytes(iv);
        System.out.println("IV is "+Base64.encodeBase64(iv)+" "+ com.sun.jersey.core.util.Base64.base64Decode(new String(Base64.encodeBase64(iv)))+ " number of bytes is "+iv.length);
        return new String(Base64.encodeBase64(iv));
}

@Override
public SecretKey generateEncryptionKey(){
    KeyGenerator aesKey = null;
    try {
        aesKey = KeyGenerator.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
    }
    aesKey.init(256);
    SecretKey secretKey = aesKey.generateKey();
    System.out.println("Encryption key is "+ new Base64().encode(secretKey.getEncoded()));
    return secretKey;
}

Below is the stacktrace for the exception Exception is at line :
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes(Charset.forName("UTF-8"))));

java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long
at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineInit(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at com.intuit.platform.publiccloudaccess.core.services.EncryptionServiceImpl.encrypt(EncryptionServiceImpl.java:47)

回答1:


You encoded your IV as Base64 before returning it from generateRandomIV. You have to decode it before using it for encryption and decryption.

cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(java.util.Base64.Decoder.decode(IV.getBytes("UTF-8"))));

Java 8 provides the java.util.Base64 class for getting different Base 64 encoders and decoders.




回答2:


Following the Rob's comment,

System.out.println("number of IV bytes is "+IV.length()+" "+IV);

Here you get the length of the IV in terms of String. However

cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes(Charset.forName("UTF-8"))));    

here you are providing the IV as byte array and making the length of the IV as 16 in therms of String does not guarantee that its byte representation is also 16 bytes. So as Rob suggested it would be better for you to keep the IV in the byte array and use it as the byte array.



来源:https://stackoverflow.com/questions/27351197/aes-256-bit-encryption-java-security-invalidalgorithmparameterexception-wrong

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!