java - AES/CBC/PKCS5Padding 加密与固定 IV(或没有)
问题描述
我需要编写一个使用 AES256、CBC 模式和 PKCS#5 填充来加密字符串的 Java 函数。我已经获得了一个密钥和一些前后示例,因此我可以验证我的实现。这就是我所拥有的。我发现预期的结果正是这个在线生成器产生的结果:https ://encode-decode.com/aes-256-cbc-encrypt-online/
我必须为我的 Cipher 实例提供的参数之一是初始化向量(“IV”)。如果我不指定一个,Java 会使用一个随机的,因此每次运行都会产生不同的结果,这不是我想要的行为。
上面的生成器不会向它的用户询问 IV,它仍然会产生与我的目标相同的结果。所以我想知道这怎么可能。人们是否倾向于使用相同的 IV(无论它是否安全),例如“0000000000000000”、“1234567812345678”(我都尝试过,以防万一)?或者有没有其他方法可以在不使用 IV 的情况下使用上述参数进行加密?
以防万一,这是我目前的代码:
package com.example.test;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class AesTest {
public static String key = "abcdefghijklmnopqrstuvwxyz012345";
public static String email = "test@example.com";
public static String initVector = "????????????????";
public static void main(String []args) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(
Cipher.ENCRYPT_MODE,
new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"),
new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8))
);
byte[] encrypted = cipher.doFinal(email.getBytes());
System.out.println(Base64.getEncoder().encodeToString(encrypted));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
解决方案
是的,如果默认情况下不是随机的,通常使用全零 IV 作为默认值。初始化向量与 CBC 的第一个明文块进行异或运算,因此如果所有字节都设置为零值,则简单地保留明文。
这可以通过对完整的明文块同时执行 ECB 和 CBC 来轻松检查。例如 ASCII 加密aaaaaaaaaaaaaaaa
,即 16 个a
字符将导致 ECB 的以下密文:
mExSanM1tVyEV1hjSqBlTZcuxSr1ybN1rpCtwYiyIYg=
这是CBC的:
mExSanM1tVyEV1hjSqBlTcZkEjmYpQWV7Nmnr0thwhw=
很明显,第一个块必须相同,因为欧洲央行不使用 IV。所以第一个块加密是直接在明文上进行的,正如您对全零 IV 的期望一样。
请注意,CBC 仅在 IV 对对手完全不可预测时才提供语义安全,即 IV 中的所有位对对手来说必须是随机的。
对于 Java,您可以IvParameterSpec
像这样创建:
new IvParameterSpec(new byte[cipher.getBlockSize()]);
推荐阅读
- python - Python如何通过知道列表中列表的第一个元素来获取列表中列表的索引?
- android - 禁用扩展时自动滚动 AppBarLayout
- r - 为什么这个 R 版本的骑士之旅不起作用?
- sublimetext3 - 如何在 Autoprefixer 的 caniuse 列表上运行更新
- php - Composer 如何从版本 1 更新到版本 2
- python - 如何访问传递给 Python 线程的函数 args?
- discord - Discord Python Rewreite - 频道搜索器
- r - 在ggplot中注释方程
- javascript - React Native Loader 在每个组件或根目录中?
- python - 我无法安装 discord.py