AES如何用不同的IV解密?

时间:2017-05-27 14:17:58

标签: java encryption cryptography

我想了解有关AES加密的更多信息。 AES加密使用密钥和IV进行加密,但由于每个IV都不同,AES如何解密密文并返回明文?

http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html https://www.securecoding.cert.org/confluence/display/java/MSC61-J.+Do+not+use+insecure+or+weak+cryptographic+algorithms

public static byte[] encrypt_cbc(SecretKey skey, String plaintext) {
        /* Precond: skey is valid; otherwise IllegalStateException will be thrown. */
        try {
            byte[] ciphertext = null;
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");           
            final int blockSize = cipher.getBlockSize();
            byte[] initVector = new byte[blockSize];
            (new SecureRandom()).nextBytes(initVector);
            IvParameterSpec ivSpec = new IvParameterSpec(initVector);
            cipher.init(Cipher.ENCRYPT_MODE, skey, ivSpec);
            byte[] encoded = plaintext.getBytes(java.nio.charset.StandardCharsets.UTF_8);
            ciphertext = new byte[initVector.length + cipher.getOutputSize(encoded.length)];
            for (int i=0; i < initVector.length; i++) {
                ciphertext[i] = initVector[i];
            }
            // Perform encryption
            cipher.doFinal(encoded, 0, encoded.length, ciphertext, initVector.length);
            return ciphertext;
        } catch (NoSuchPaddingException | InvalidAlgorithmParameterException | ShortBufferException |
            BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException e)
        {
            /* None of these exceptions should be possible if precond is met. */
            throw new IllegalStateException(e.toString());
        }
    }

    public static String decrypt_cbc(SecretKey skey, byte[] ciphertext)
        throws BadPaddingException, IllegalBlockSizeException /* these indicate corrupt or malicious ciphertext */
    {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");           
            final int blockSize = cipher.getBlockSize();
            byte[] initVector = Arrays.copyOfRange(ciphertext, 0, blockSize);
            IvParameterSpec ivSpec = new IvParameterSpec(initVector);
            cipher.init(Cipher.DECRYPT_MODE, skey, ivSpec);
            byte[] plaintext = cipher.doFinal(ciphertext, blockSize, ciphertext.length - blockSize);
            return new String(plaintext);
        } catch (NoSuchPaddingException | InvalidAlgorithmParameterException |
            InvalidKeyException | NoSuchAlgorithmException e)
        {
            /* None of these exceptions should be possible if precond is met. */
            throw new IllegalStateException(e.toString());
        }
    }

1 个答案:

答案 0 :(得分:1)

一般随机IV - CBC需要不可预测的 IV - 在密文前面加上&#34;删除&#34;在解密之前。我删除了引号,因为删除它也可能是复制它并在之后跳过它。原则上它可以放置在密文附近的任何地方。 CBC模式的IV等于底层密码的块大小(Cipher#getBlockSize()),即AES的16字节,因此大小是预先知道的。

IV不需要对攻击者保密。

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

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