gpt4 book ai didi

java - 如何使用 AES/CBC/PKCS5Padding 生成 AES key 进行加密和解密

转载 作者:行者123 更新时间:2023-11-30 05:25:59 24 4
gpt4 key购买 nike

我正在尝试使用此代码创建 AES key

    public static SecretKey generateSecretKey() {

KeyGenerator generator;
try {

generator = KeyGenerator.getInstance(StaticHandler.AES_KEY_MODE); // Is "AES"
generator.init(StaticHandler.AES_KEY_SIZE); // The AES key size in number of bits // Is "128"

return generator.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

但是使用此代码进行加密/解密


public static String encrypt(String data, SecretKey secret, Charset charset) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);

return new String(cipher.doFinal(data.getBytes()), charset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}


public static String decrypt(String data, @NonNull SecretKey secret, Charset charset) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret);

return new String(cipher.doFinal(data.getBytes()), charset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

收到错误java.security.InvalidKeyException:参数丢失

我猜我需要添加一些盐,尽管我不知道如何使用生成的 key 来做到这一点。我想避免生成密码,但如果它是安全生成的密码,我不会介意。

编辑:事后想一想,如果我通过网络发送数据包,我应该使用 GCM 还是 CBC 加密?请记住,我使用的是随机生成的 key ,并且不会为每个客户端和服务器 session 随机生成的 session 保留它们。

最佳答案

不,你不需要盐,而且你的 key 实际上没问题。 CBC 模式需要 IV(初始化 vector ),see wikipedia 、IV 对于每条加密数据应该不同,但每次解密必须使用与相应加密相同的值。 (补充)对于 CBC 来说,虽然不是其他一些模式,但 IV 不能被对手预测对于安全来说也至关重要;实现唯一性和不可预测性的最简单和最常见的方法是使用安全随机数(又名位)生成器,例如 Java 的 SecureRandom。如果您想了解其他方法,这实际上并不是一个编程问题,并且更适合 crypto.SX 或 security.SX,其中已经有几个 Q。

您可以显式生成 IV 并将其指定为加密和解密,或者允许加密操作本身生成 IV,从加密密码中获取它,并将其指定为解密密码。无论哪种情况,加密者都必须提供解密者将使用的值;一种常见的方法是简单地将 IV 与密文连接起来(使得它们很容易保持正确匹配),但同样还有关于加密和安全性的其他方法讨论。请参阅https://docs.oracle.com/en/java/javase/11/security/java-cryptography-architecture-jca-reference-guide.html在名为“初始化密码对象”(方法声明的盒装 block 之后的两段)和“管理算法参数”的部分中。

<小时/>

另外不要将密文存储在字符串中。 Java String 旨在处理有效字符而不是任意字节。将密文“解码”为字符串并将其“编码”回二进制几乎总是会丢失或更改一些数据,特别是如果您允许两端的字符集不同,并且使用现代密码学对密文进行任何更改将破坏您的全部或大部分数据。由于密文字节,因此最好将其处理为byte[];如果这是不可能的,因为您想将其放入 URL 等 is 字符中,请使用旨在将任意字节编码为文本的多种方案之一,以便可以正确恢复它们:base64 ( 3 或 4 个主要变体,加上许多次要变体)、base32、十六进制/base16、URL“百分比”编码、MIME 引用打印、yencode、Kermit、PPP 等。 j8+ java.util.Base64提供较新的 base64 变体(即不是 uuencode)。

相反,虽然现代加密中的“明文”实际上可以是任何形式的数据,但如果您的数据确实是文本并且属于字符串,那么您应该使用加密前使用合适的字符集,解密后使用相同字符集进行解码,即

 byte[] ctext = encCipher.doFinal (input.getBytes(charset));
...
String output = new String (decCipher.doFinal (ctext), charset);

虽然“最佳”字符集可能会根据您的数据而有所不同,但如果您不知道数据是什么或不想费心分析它,UTF-8 相当不错对于大多数文本数据来说非常流行和标准。

关于java - 如何使用 AES/CBC/PKCS5Padding 生成 AES key 进行加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58599423/

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