【问题标题】:java AES_CFB Mode decryption not in stream modejava AES_CFB模式解密不在流模式下
【发布时间】:2016-12-13 22:00:46
【问题描述】:
 Cipher cipher = Cipher.getInstance("AES/CFB128/NoPadding");
 SecretKeySpec keySpec = new SecretKeySpec("1234567890123456".getBytes(), "AES");
 byte[] iv = "1234567890123456".getBytes();
 cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
 Cipher decryptCipher = Cipher.getInstance("AES/CFB128/NoPadding");
 decryptCipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
 byte[] data = cipher.doFinal("1234567890123456".getBytes());

 for (byte b : data) {
    byte[] output = decryptCipher.update(new byte[]{b});
    System.out.println(new String(output));
 }

我使用 JCE 解密一些使用 AES_128_CFB 加密的数据,但我发现 decrycipher.update 会在前 15 次返回一个空数组。 decryptCipher 的块大小为 16。CFB 密码应该在流模式下工作吗?我在 golang 中重新测试了这段代码,它工作正常。

【问题讨论】:

    标签: java encryption cfb-mode


    【解决方案1】:

    仅仅因为分组密码模式原则上可以与位精度流一起使用并不意味着实现此模式的 API 必须遵守这一点。 CFB-128 使用 128 位的段大小,这意味着一次加密需要 16 个字节,这恰好也是块大小。它可以在要加密的数据到达之前提前创建密钥流的一部分(与段大小相同)。

    解释此行为的一种可能方法是查看如果行为从提前生成密钥流或在完整段到达后生成密钥流发生变化,代码将如何变化。一个可能更容易实现或阅读另一个。现在,我并不是说具有这种行为的代码一定更容易阅读,而是说 JCE 的类图相当复杂,这可能是实现 CFB 的一种简单方法。

    这样做的另一个原因可能是限制密钥流在进程内存中可用的时间量。例如,如果预先计算了密钥流(这意味着Cipher#update 具有与其输入相同的输出大小),我们可能会遇到密钥流的一部分在内存中可用并且可以被同一台机器上的另一个进程。如果密钥流不是预先生成的,那么它只会在需要时存在,因此只有很短的时间。
    如果我们进一步思考,我们会发现攻击者是否可以访问密钥流,他们还可以访问 AES 的子密钥。如果他们不能这样做,他们当然可以访问密文和明文来计算密钥流。这对他们是否有用是另一个问题,但通常不是。

    在CFB模式下唯一必须做到的是输入和输出的大小相同,并且只有在调用Cipher#doFinal之后才能检查。

    【讨论】:

    • 如何实现面向流的 AES 服务器
    • 这是一个完全不同的问题,我不知道这是否容易实现。为什么你需要它?
    猜你喜欢
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2015-11-18
    • 2017-02-02
    • 2011-06-07
    • 2012-10-03
    • 1970-01-01
    相关资源
    最近更新 更多