我在正确加密 AES256 字符串时遇到困难。我的要求是它需要是 AES256 和 CBC,并且长度为 24 的 IV 需要添加到加密字符串上。我已经有一个提供的 key 并且它保持不变。
我的代码
public String encrypt(String value) {
try {
SecureRandom secureRandom = new SecureRandom();
byte[] ivBytes = new byte[16];
secureRandom.nextBytes(ivBytes);
SecretKeySpec skeySpec = new SecretKeySpec(byteArray, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(ivBytes));
byte[] encrypted = cipher.doFinal(value.getBytes());
Log.d("encrypted", String.format("%s", encrypted.length));
return Base64.encodeToString(ivBytes, Base64.DEFAULT) + Base64.encodeToString(encrypted, Base64.DEFAULT);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
这里有几个问题。如果我将 ivBytes 的 16 更改为 24,则会收到一条错误消息,指出预期的 iv 长度是 16 而不是 24。我也不确定此代码是否使用 AES256 或 AES 进行加密。任何帮助表示赞赏。顺便说一句,值是十六进制,例如,它可能类似于 831684e1。不确定这是否会影响加密。
最佳答案
Couple issues here. If I change 16 to 24 for the ivBytes, I get an error that says expected iv length is 16 not 24.
这是正确的。 AES 仅定义了 128 位/16 字节的 block 大小。 CBC需要单个 block 大小的随机(化)IV。
I also am not sure if this code is encrypting in AES256 or AES.
我们也不确定,因为未指定 byteArray
,并且 Java/Android 中的 AES 实现使用 key 大小在 AES-128、-192 或 -256 之间进行选择。请注意, key 还应由随机字节组成(而不是编码为字节的密码)。 Android 没问题,但对于 Java,您可能需要旧版本 Java 运行时环境 (JRE) 的无限加密文件。
不用说,对于 AES-256,byteArray
应该是 32 字节。
Btw, value is a hexadecimal, for example, it could be something like 831684e1. Not sure if this affects encryption.
通常,十六进制是二进制值的表示。您可能最好先解码十六进制值,然后加密二进制值。这将使密文数量减少一半(并且也遵守其他开发人员最少惊讶的原则)。
当前您正在使用 value.getBytes()
这意味着您将获得平台特定的十六进制字符编码(Android 为 UTF-8,但您基本上会获得 US-ASCII 作为十六进制始终编码为每个字符一个字节)。换句话说,您可以对二进制值进行两次编码,而根本不需要编码。
关于java - AES256 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50440658/