【问题标题】:AES encryption in CBC mode with an inline IVCBC 模式下的 AES 加密,带有内联 IV
【发布时间】:2016-04-20 12:43:31
【问题描述】:

我想实现这段代码,即CBC模式下的AES加密,带有内联IV,但是有这个错误消息:

IV 长度错误:必须为 16 字节长

代码是:

package implementaes;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec;

public class Aesaesaes
{
    public static void main(String[] args)
    {
        try
        {
                //Lookup a key generator for the AES cipher
                        KeyGenerator kg = KeyGenerator.getInstance("AES");
            SecretKey key = kg.generateKey();

            SecretKeySpec keySpec = new
                        SecretKeySpec(key.getEncoded(), "AES");     
                //Lookup an instance of a AES cipher
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

                //initialize IV  manually

                byte[] ivBytes = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

                //create IvParameterSpecobject

                IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);     

               //Initialize the cipher using the secter key

            cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivSpec);

                String plainText = "This is a secret!";



            byte[] cipherText = cipher.doFinal(plainText.getBytes());

            System.out.println("Resulting Cipher Text:\n");
            for(int i=0;i<cipherText.length;i++)
            {
                System.out.print(cipherText[i] + " ");
            }
            System.out.println("");



        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

我该如何解决?顺便说一句,我试过了:

byte[] ivBytes = new byte[] {0x00,0x00,0x00,0x00};

为 16 字节,但不起作用

【问题讨论】:

    标签: java encryption bytearray aes initialization-vector


    【解决方案1】:

    您定义的 ivBytes 当前为 8 个字节:

    byte[] ivBytes = new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    

    ivBytes 数组中的每个成员代表一个字节。您需要一个包含 16 个条目的数组:

    byte[] ivBytes = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};  
    

    更新 我认为很明显,您将为 IV 提供您自己的值,但可能值得指出 Dave 的评论,即不将 IV 初始化为全零符合您的最佳利益。见how to pick an IV

    【讨论】:

    • 每个单元格只有 8 位宽。 0x00 是 0,而 0 适合这 8 位。您选择在 java 中将 0 表示为 0x00 的事实不会改变数组中每个单元格的宽度。
    • 或者对于零,只需执行= new byte[16]; - 该表单分配指定的大小,所有元素为零(如果是对象数组,则为 null)。 @Tung 请注意,根据加密的用途,使用包括零在内的常量 IV 通常是不安全的; CBC 存在 IV 的全部原因是独特且不可预测。 OTOH,您已经丢弃了密钥,因此您实际上使合法接收者和对手一样困难。
    • @dave_thompson 答案中的值仅用于演示目的(任何其他建议的值可能已经抛弃了 OP,但你为他们澄清这一点很好)。
    猜你喜欢
    • 1970-01-01
    • 2021-02-13
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 2022-12-16
    • 2011-07-03
    • 2019-09-30
    相关资源
    最近更新 更多