java - 如何处理 AES CTR 的 IV/Nonce/Counter?

标签 java encryption aes nonce ctr-mode

import javax.crypto.Cipher;

public abstract class Crypto {


    private static final String CIPHER_ALGORITHM = "AES/CTR/NoPadding";
    private String AesKeyString = "ByWelFHCgFqivFZrWs89LQ==";

    private void setKey() throws NoSuchAlgorithmException{
        byte[] keyBytes;
        keyBytes = Base64.getDecoder().decode(AesKeyString);
        aesKey = new SecretKeySpec(keyBytes, "AES");
    }

    protected byte[] execute(int mode, byte[] target, byte[] iv) 
            throws Exception{
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(mode, aesKey, ivSpec);
        return cipher.doFinal(target);
    }

}

根据NIST Recommendation - 附录 B,有两种有效的方法来构造初始计数器 block (AES 是 128 位 block 密码):

  1. 128 位随机数与 m 位计数器值(通常为 32 位)进行异或。
  2. 64 位随机数前置到 64 位计数器。

我的问题是:

  • 关于所使用的初始计数器 block 的确切过程是什么 在 javax.crypto.Cipher 的“AES/CTR/NoPadding”实例中(假设 SunJCE 作为提供者)? 也就是说,给定上述代码,使用先前的哪种初始计数器 block 方法(如果有)?

最佳答案

Java 只是让您自行选择构造计数器的方式。您只需使用 16 字节 IV 初始化 CTR 模式,这只不过是初始计数器值。

一旦开始加密,它将使用超过 128 位的计数器。话又说回来,您几乎不希望它重新开始,因为这会直接损害明文的安全性。缺点是不直接支持 32 位 XOR 方法(如果从 FFFFFFFF 计数器开始,下一个值将更改计数器的第 33 个最低有效位)。

话又说回来,我宁愿选择 8 字节随机数并将最低有效位设置为全零。或者当然选择GCM模式。


证明:

Cipher aesCTR = Cipher.getInstance("AES/CTR/NoPadding");
SecretKey aesKey = new SecretKeySpec(new byte[16], "AES");
IvParameterSpec lastIV = new IvParameterSpec(Hex.decode("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF"));
aesCTR.init(Cipher.ENCRYPT_MODE, aesKey, lastIV);
byte[] twoBlocks = aesCTR.doFinal(new byte[2 * aesCTR.getBlockSize()]);
byte[] secondBlock = Arrays.copyOfRange(twoBlocks, 16, 32);
System.out.printf("%s%n", Hex.toHexString(secondBlock));

IvParameterSpec firstIV = new IvParameterSpec(new byte[16]); // all zero IV
aesCTR.init(Cipher.ENCRYPT_MODE, aesKey, firstIV);
byte[] oneBlock = aesCTR.doFinal(new byte[aesCTR.getBlockSize()]);
System.out.printf("%s%n", Hex.toHexString(oneBlock));

输出:

66e94bd4ef8a2c3b884cfa59ca342b2e
66e94bd4ef8a2c3b884cfa59ca342b2e

关于java - 如何处理 AES CTR 的 IV/Nonce/Counter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42836844/

相关文章:

java - 唯一地将 Android 应用程序连接到 PC 上的 Java 小程序

Java AES/GCM 解密失败

php - 使用加密密码安全地将php连接到mysql

java - AES 随 secret 钥生成

java - 在 Hibernate 中获取所有 session 缓存的对象

java - 删除java中的类对象

ssl - 启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件

java - Java 中的加密和 Flutter 中的解密 (AES-256)

c - 来自/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 的段错误

java - 简单的双向 RMI SSL 连接,PKIX 路径构建失败