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

Java AES-CTR双重加密将密文反转为明文,java,encryption,aes,javax.crypto,ctr-mode,Java,Encryption,Aes,Javax.crypto,Ctr Mode,当我尝试用相同的密钥再次加密密文时,它会生成原始明文 使用的算法是AES和计数器模式键和IV保持不变 这就是算法应该表现的方式吗?如果,作为Cipher.init()的第一个参数给出的Cipher.ENCRYTMODE有什么用 这是我测试的示例程序 import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class Encryp

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

使用的算法是AES和计数器模式IV保持不变

这就是算法应该表现的方式吗?如果,作为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));
    }
}

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

plaintext XOR AES-CTR(nonce, key) = ciphertext
XOR操作的工作方式是,使用键
k
x
进行两次XORing操作,再次导致
x

x ^ k ^ k = x
这就是为什么加密和解密在CTR模式下对分组密码的操作完全相同(无nonce生成并将其放入密文中)

如果您不希望加密和解密算法是相同的,那么您应该使用不同的模式,例如CBC,但是这类事情没有错


请注意,为了确保CTR模式的安全,每次加密都必须在同一密钥下使用不同的nonce/IV。

更改2。AESChipher.init(…)到Cipher.DECRYPT_模式不需要生成原始文本。请运行示例程序。您的第一个版本包含“解密”而不是“双重加密”@Sudershan I get
java.security.InvalidKeyException:非法密钥大小
尝试运行此程序?@mp911de是的,很抱歉。