我想尝试加密一个文件,使用了以下stackoverflow response,但在测试初始化向量时,我发现它只影响前16个字节。当我将一个空的iv传递给解密密码(除了前16个字节之外),数据被意外地解密了。[我假设库没有问题,我做错了什么;但其他人可能也处于同样的困境,却没有意识到。]
注意:刚才我找到了一个5.5年前的stack overflow post,发现了同样的问题;不幸的是,它仍然没有得到回应。
``` package test;
import java.security.AlgorithmParameters; import java.security.spec.KeySpec; import java.util.Formatter; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec;
/* * 问题:使用“AES/CBC/PKCS5Padding”加密时,初始化向量只影响第一个块?! * * 示例输出: * iv 1e6376d5d1180cf9fcf7c78d7f1f1b96 * bv 00000000000000000000000000000000 * I: 222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 * E: b35b3945cdcd08e2f8a65b353ff754c32a48d9624e16b616d432ee5f78a26aa295d83625634d1048bf2dbb51fc657b7f796b60066129da5e1e7d3c7b51a30c1d962db75ac6666d4b32513c154b47f18eb66f62d7417cfd77f07f81f27f08d7d818e6910ca5849da3e6cff852bc06317e2d51907879598c8d3ae74074f4c27f7b8e2f74ca04d3ed6ac839b819a0f4cb462d0a4d9497cd917b8bd0aafb590ddd593b5b652cf8f642d3b2cd9dc0981dc1c913d52d065a844ea65e72cd7738eee3b488c4304e884109320dc54668ac4659d6014de9cf19422f7f68157d4330478589533571434d07b1939e56259fb8828823361bc912b84dc6ccdd5878b1d05801e0a6ce099bc86f1356fd145338163d59a07f2efdb1a6f91f4a35e6304f2d15d9972b0dda3c2275b5942a7f032ab6f90138 * D: 3c4154f7f33a2edbded5e5af5d3d39b422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 */ public class IvBug {
public static void main(String[] args) throws Exception { // 初始化。 final char[] password = "foo".toCharArray(); final byte[] salt = "bar".getBytes();
byte[] iData = new byte[300]; java.util.Arrays.fill(iData, (byte)0x22); // 使问题更容易看到。 // for (int i=0; i<msg.length; i++) msg[i] = (byte) i; // 替
Example:
Initial bytes ..... 2222222222222222222222222222222222222222222222222222
Encrypted bytes ... b35b3945cdcd08e2f8a65b353ff754c32a48d9624e16b616d432
Decrypted bytes ... 3c4154f7f33a2edbded5e5af5d3d39b422222222222222222222
Q: Why isn't the entire decryption failing?
假设我可以通过每次迭代16个字节并通过哈希先前加密的16个字节块更新iv来进行加密。然而,这似乎是繁琐的工作,我本来期望库会自己完成。我也希望这些专家在提供实施指南时会提到它。但我只是在瞎猜。说不定安全社区只担心对第一个块的黑客攻击。注意:刚才我找到了一个5.5年前的stack overflow post,发现了同样的问题;不幸的是,它仍然没有得到回应。
``` package test;
import java.security.AlgorithmParameters; import java.security.spec.KeySpec; import java.util.Formatter; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec;
/* * 问题:使用“AES/CBC/PKCS5Padding”加密时,初始化向量只影响第一个块?! * * 示例输出: * iv 1e6376d5d1180cf9fcf7c78d7f1f1b96 * bv 00000000000000000000000000000000 * I: 222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 * E: b35b3945cdcd08e2f8a65b353ff754c32a48d9624e16b616d432ee5f78a26aa295d83625634d1048bf2dbb51fc657b7f796b60066129da5e1e7d3c7b51a30c1d962db75ac6666d4b32513c154b47f18eb66f62d7417cfd77f07f81f27f08d7d818e6910ca5849da3e6cff852bc06317e2d51907879598c8d3ae74074f4c27f7b8e2f74ca04d3ed6ac839b819a0f4cb462d0a4d9497cd917b8bd0aafb590ddd593b5b652cf8f642d3b2cd9dc0981dc1c913d52d065a844ea65e72cd7738eee3b488c4304e884109320dc54668ac4659d6014de9cf19422f7f68157d4330478589533571434d07b1939e56259fb8828823361bc912b84dc6ccdd5878b1d05801e0a6ce099bc86f1356fd145338163d59a07f2efdb1a6f91f4a35e6304f2d15d9972b0dda3c2275b5942a7f032ab6f90138 * D: 3c4154f7f33a2edbded5e5af5d3d39b422222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 */ public class IvBug {
public static void main(String[] args) throws Exception { // 初始化。 final char[] password = "foo".toCharArray(); final byte[] salt = "bar".getBytes();
byte[] iData = new byte[300]; java.util.Arrays.fill(iData, (byte)0x22); // 使问题更容易看到。 // for (int i=0; i<msg.length; i++) msg[i] = (byte) i; // 替