需要解决AES中错误的IV长度问题

我正在尝试在Java中实现AES,这是我使用的代码:

byte[] sessionKey = {00000000000000000000000000000000}; byte[] iv = {00000000000000000000000000000000}; byte[] plaintext = "6a84867cd77e12ad07ea1be895c53fa3".getBytes(); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv)); byte[] ciphertext = cipher.doFinal(plaintext); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv)); byte[] deciphertext = cipher.doFinal(ciphertext); 

我需要这个固定密钥和IV用于测试目的,但我得到以下exception:

 Exception in thread "main" java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long at com.sun.crypto.provider.SunJCE_h.a(DashoA12275) at com.sun.crypto.provider.AESCipher.engineInit(DashoA12275) at javax.crypto.Cipher.a(DashoA12275) at javax.crypto.Cipher.a(DashoA12275) at javax.crypto.Cipher.init(DashoA12275) at javax.crypto.Cipher.init(DashoA12275) 

如何在此AES实现中使用此固定IV? 有什么办法吗?

首先,

 byte[] iv = {00000000000000000000000000000000}; 

创建一个大小为1的字节数组,而不是一个大小为32的字节数组(如果这是你的意图)。

其次,AES的IV大小应该是16字节或128位(这是AES-128的块大小)。 如果使用AES-256,则IV大小应为128位大,因为AES标准仅允许128位块大小。 原始Rijndael算法允许其他块大小,包括256位长块大小。

第三,如果您打算使用AES-256,这不是开箱即用的。 您需要下载并安装JCE Unlimited Strength Jurisdiction Policy Files (滚动到页面底部); 我还建议阅读随附的许可证。

这将导致您的代码发生以下更改:

 byte[] iv = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 

最后,初始化向量意味着唯一且不可预测。 16个字节的序列,每个字节由值0表示,不适合IV。 如果这是生产代码,请考虑获取帮助。

来自高级加密标准 :

该标准包括三个分组密码,AES-128,AES-192和AES-256,采用最初发布为Rijndael的大型系列。 这些密码中的每一个都具有128位块大小 ,密钥大小分别为128,192和256位

(重点补充)

从初始化向量 :

对于分组密码操作模式,IV通常与密码的块大小一样大

将这两个因素结合在一起,您可以得到AES始终为128位AES,与密钥大小无关。

这里的AES可能是AES-128而不是AES-256。如果要启用AES-256,则必须包含额外的jar,因为有适当的出口控制策略。 所以先检查一下。 在大多数情况下,AES-128就足够了。

您的IV不能超过128位,即AES-128时为16字节。 所以改变初始化向量长度。

那必须奏效。 另请阅读此http://en.wikipedia.org/wiki/Initialization_vector

警告:固定IV不是一个好习惯。 它必须是随机的或伪随机的,才能提供更好的安全性。

为什么不使用类似的东西而不是使用“魔术数字”:

 SecureRandom random = new SecureRandom(); byte[] iv = random.generateSeed(16); 

所以你的iv有16个随机字节。