gpt4 book ai didi

java - 使用 AES 加密和连续解密后数据不同

转载 作者:行者123 更新时间:2023-12-01 18:47:15 24 4
gpt4 key购买 nike

我想使用 AES 加密和解密整数,但无法实现。

为了测试基本的加密过程,我编写了一个简单的方法,该方法获取输入数据,使用相同的参数对其进行加密和解密,然后返回结果。

这是我失败的 JUnit 测试用例,用于检查输入和输出数据是否相等。

    @Test
public void test4() throws UnsupportedEncodingException {

Random random = new Random();

SecretKey secretKey = Tools.generateKey("secretKey".getBytes("UTF-8"));

byte[] initializationVector = Tools.intToByteArray(random.nextInt());
// ensuring that the initialization vector has the correct length
byte[] ivHash = Tools.hashMD5(initializationVector);

int value = random.nextInt();
byte[] input = Tools.intToByteArray(value);

byte[] received = Tools.enDeCrypt(input, secretKey, ivHash);
assertEquals(data.hashCode(), received.hashCode());
}

方法生成 key :

public static SecretKeySpec generateKey(byte[] secretKey) {

try {
// 256 bit key length
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(secretKey);
byte[] key = md.digest();
return new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

int -> byte[] 转换方法:

public static byte[] intToByteArray(int a) {
// block size is 128 bit, thus I append zeros

byte[] intByte = ByteBuffer.allocate(4).putInt(a).array();
byte[] longerIntByte = new byte[16];
for (int i = 0; i < 4; i++) {
longerIntByte[i] = intByte[i];
}
for (int i = 4; i < longerIntByte.length; i++) {
longerIntByte[i] = 0;
}
return longerIntByte;
}

下面是加密和解密的代码:

public static byte[] enDeCrypt(byte[] data, SecretKey secretKey,
byte[] initialisationVector) {

try {
IvParameterSpec ivSpec = new IvParameterSpec(initialisationVector);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");

cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
byte[] encrypted = cipher.doFinal(data);

cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;

} catch (NoSuchAlgorithmException | NoSuchPaddingException
| InvalidKeyException | InvalidAlgorithmParameterException
| IllegalBlockSizeException | BadPaddingException e) {
throw new RuntimeException(e);
}

}

最佳答案

assertEquals(data.hashCode(), receive.hashCode()) 不太可能通过,除非 datareceived 引用相同的对象(因为字节数组继承了 Object 的身份哈希码方法)。我不知道 data 来自哪里,但这里的情况可能并非如此。您应该使用Arrays.equals(data, returned)

除此之外,这里还存在各种加密问题:

  • 对于加密目的而言,随机性还不够“随机”;您应该使用 SecureRandom。
  • 使用普通 SHA-256 派生 key 是值得怀疑的。您应该考虑使用专门为此设计的 key 派生算法,例如 PBKDF2。
  • 具有 256 位 key 的 AES 并不总是比 128 位 key 更好。检查this page 。在这种情况下,它完全是假的,因为密码短语很少达到 128 位的熵。
  • 随机 IV – 很好,但是当您可以直接使用 SecureRandom.nextBytes() 时为什么要跳过这些麻烦呢?对 IV 进行哈希处理不会添加任何有用的内容。
  • 当您可以让库处理它时,没有理由进行手动零填充。只需指定 PKCS5Padding 而不是 NoPadding。

关于java - 使用 AES 加密和连续解密后数据不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17261819/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com