AES 如何使用不同的 IV 进行解密?

ilo*_*arn 5 java encryption cryptography

我正在尝试了解有关 AES 加密的更多信息。AES 加密同时使用密钥和初始化向量(IV)进行加密,但由于每个IV都不同,那么AES如何解密密文并返回明文呢?

\n\n

\xc2\xa0

\n
public static byte[] encrypt_cbc(SecretKey skey, String plaintext) {\n    /* Precondition: skey is valid; otherwise IllegalStateException will be thrown. */\n    try {\n        byte[] ciphertext = null;\n        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");\n        final int blockSize = cipher.getBlockSize();\n        byte[] initVector = new byte[blockSize];\n        (new SecureRandom()).nextBytes(initVector);\n        IvParameterSpec ivSpec = new IvParameterSpec(initVector);\n        cipher.init(Cipher.ENCRYPT_MODE, skey, ivSpec);\n        byte[] encoded = plaintext.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n        ciphertext = new byte[initVector.length + cipher.getOutputSize(encoded.length)];\n        for (int i=0; i < initVector.length; i++) {\n            ciphertext[i] = initVector[i];\n        }\n        // Perform encryption\n        cipher.doFinal(encoded, 0, encoded.length, ciphertext, initVector.length);\n        return ciphertext;\n    } catch (NoSuchPaddingException | InvalidAlgorithmParameterException | ShortBufferException |\n        BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException e)\n    {\n        /* None of these exceptions should be possible if the precondition is met. */\n        throw new IllegalStateException(e.toString());\n    }\n}\n\npublic static String decrypt_cbc(SecretKey skey, byte[] ciphertext)\n    throws BadPaddingException, IllegalBlockSizeException /* These indicate corrupt or malicious ciphertext */\n{\n    try {\n        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");\n        final int blockSize = cipher.getBlockSize();\n        byte[] initVector = Arrays.copyOfRange(ciphertext, 0, blockSize);\n        IvParameterSpec ivSpec = new IvParameterSpec(initVector);\n        cipher.init(Cipher.DECRYPT_MODE, skey, ivSpec);\n        byte[] plaintext = cipher.doFinal(ciphertext, blockSize, ciphertext.length - blockSize);\n        return new String(plaintext);\n    } catch (NoSuchPaddingException | InvalidAlgorithmParameterException |\n        InvalidKeyException | NoSuchAlgorithmException e)\n    {\n        /* None of these exceptions should be possible if precond is met. */\n        throw new IllegalStateException(e.toString());\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Maa*_*wes 1

通常,随机 IV(CBC 需要不可预测的IV)会作为密文的前缀,并在解密之前“删除”。我已将删除放在引号中,因为删除它也可能是复制它并随后跳过它。原则上它可以放置在密文附近的任何地方。CBC 模式的 IV 等于底层密码 ( Cipher#getBlockSize()) 的块大小,即 AES 的 16 字节,因此大小是预先已知的。

IV 不需要对攻击者保密。

一般来说,IV 的类型和安全性取决于加密模式。对于 CBC,它需要是不可预测的;对于 CTR(计数器模式),它不应与另一个计数器值重叠;对于 GCM,它需要是 12 字节随机数。

还有其他共享 IV 的方法。例如,对于 CBC,可以在两侧保留一个计数器并加密该计数器以形成 IV(当然,在将其编码为 16 字节之后)。这样密文中就不需要包含 IV。