AES-CTR双重加密将密文反转为明文

Sud*_*han 2 java encryption aes javax.crypto ctr-mode

当我尝试使用相同的密钥再次加密密文时,它会生成原始的明文。

使用的算法是带有计数器模式的AESKeyIV保持不变。

这是算法应该表现的方式吗?如果作为 Cipher.init() 的第一个参数给出的Cipher.ENCRYTMODE有什么用?

这是我测试过的示例程序,

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class EncryptionTest {

    public static void main(String[] args) throws Exception {
        SecretKeySpec key = null;
        IvParameterSpec ivSpec = null;
        byte[] keyBytes = "usethiskeyusethiusethiskeyusethi".getBytes();
        byte[] ivBytes = "usethisIusethisI".getBytes();
        key = new SecretKeySpec(keyBytes, "AES"); //No I18N
        ivSpec = new IvParameterSpec(ivBytes);

        Cipher AesCipher = Cipher.getInstance("AES/CTR/NoPadding");


        byte[] byteText = "Your Plain Text Here".getBytes();

        AesCipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        byte[] byteCipherText = AesCipher.doFinal(byteText);
        System.out.println("Encrypted : " + new String(byteCipherText));

        AesCipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
        byte[] bytePlainText = AesCipher.doFinal(byteCipherText);
        System.out.println("Double Encrypted : " + new String(bytePlainText));
    }
}
Run Code Online (Sandbox Code Playgroud)

Art*_* B. 5

是的,这是预期的行为。分组密码的 CTR 操作模式使分组密码成为流密码。由于流密码的工作方式是生成密钥流并将密钥流与明文进行异或以生成密文:

plaintext XOR AES-CTR(nonce, key) = ciphertext
Run Code Online (Sandbox Code Playgroud)

XOR 运算的工作方式是x与一个密钥进行k两次异或运算,再次得到x

x ^ k ^ k = x
Run Code Online (Sandbox Code Playgroud)

这就是为什么 CTR 模式下分组密码的加密和解密操作完全相同(无需生成随机数并将其放入密文中)。

如果你不希望加密和解密算法相同,那么你应该使用不同的模式,例如CBC,但这种事情并没有什么问题。

请注意,为了确保 CTR 模式的安全,您必须在每次加密时使用相同密钥下的不同随机数/IV。