繁体   English   中英

AES - 在 Java 中存储带有密文的 IV

[英]AES - Storing IV with Ciphertext in Java

我已经实现了 CBC 模式 AES 加密和解密机制,其中我为推荐的每次加密尝试生成随机 IV 和随机密钥。

现在,我将密钥保存在一个单独的文件中,IV 保存在另一个文件中,但是在浏览了不同的论坛之后,我发现 IV 不应该保持安全,并且应该在加密和解密时附加密文我们可以从该密码字节数组中提取 16 个字节。

现在,我尝试了一段代码来达到同样的效果,但结果并不好,因为第一个块没有正确加密; 但是该块的 rest 可以。

有人可以告诉我我的方法有什么问题吗?

任何帮助将不胜感激谢谢:)。

public static byte[] encrypt (byte[] plaintext,SecretKey key,byte[] IV ) throws Exception {

        //Get Cipher Instance
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        //Create SecretKeySpec
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

        //Create IvParameterSpec
        IvParameterSpec ivSpec = new IvParameterSpec(IV);

        System.out.println( "IV encrypt= " + ivSpec );

        //Initialize Cipher for ENCRYPT_MODE
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        //Perform Encryption
        byte[] cipherText = cipher.doFinal(plaintext);

        ByteArrayOutputStream b = new ByteArrayOutputStream();

        b.write(IV);
        b.write( cipherText );

        return b.toByteArray();
    }

--------------------------------------------------------------------------
public static String decrypt (byte[] cipherText, SecretKey key ) throws Exception
    {
        //Get Cipher Instance
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        //Create SecretKeySpec
        SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");

        byte[] iv = Arrays.copyOfRange( cipherText , 0, 16);

        //Create IvParameterSpec
        IvParameterSpec ivSpec = new IvParameterSpec(iv);

        //Initialize Cipher for DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE, keySpec,ivSpec);

        //Perform Decryption
        byte[] decryptedText = cipher.doFinal(cipherText);

        return new String(decryptedText);
    }

----------------------------------------------------------------------------

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128);

        // Generate Key
        SecretKey key = keyGenerator.generateKey();

        // Generating IV.
        byte[] IV = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(IV);

        System.out.println("Original Text  : " + plainText);

        byte[] cipherText = encrypt(plainText.getBytes("UTF-8") ,key, IV);



        String decryptedText = decrypt(cipherText,key, IV);
        System.out.println("DeCrypted Text : "+decryptedText);

结果

Original Text  : This is a plain text which need to be encrypted by AES Algorithm with CBC Mode
DeCrypted Text : ûª¯Î¥pAï2EÞi+¼‹Ý$8ŶÄDDNâOæàtext which need to be encrypted by AES Algorithm with CBC Mode

仅仅因为您在这里复制了 IV:

byte[] iv = Arrays.copyOfRange( cipherText , 0, 16);

并不意味着当您尝试在以下期间解密它时它仍然不存在:

byte[] decryptedText = cipher.doFinal(cipherText);

您应该解密前 16 个字节之外的所有ciphertext 目前,您还在 IV 上执行 AES 解密 - 这就是您收到垃圾的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM