【发布时间】:2014-10-08 21:54:55
【问题描述】:
我正在尝试对某些文本实施 AES 加密,并且我一直在寻找一种解决方案,最终归结为一个用于加密和解密的密码。我在这个网站上找到了一个可行的解决方案:Simple Java AES encrypt/decrypt example
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Encryptor {
public static String encrypt(String key1, String key2, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string:"
+ Base64.encodeBase64String(encrypted));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key1, String key2, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key1 = "Bar12345Bar12345"; // 128 bit key
String key2 = "ThisIsASecretKet";
System.out.println(decrypt(key1, key2,
encrypt(key1, key2, "Hello World")));
}
}
这个算法使用 key1 和 key2 并且不明白为什么他们需要这两个。每个密钥的用途是什么?让 key1 一直保持原样并用个人密码替换 key2 是否安全?
谢谢
【问题讨论】:
-
为避免字符编码问题,总是在调用
String.getBytes()和new String()时指定一个字符集。 -
在互联网上你会发现很多加密样本,低至 1% 的样本会编译运行,并且会严重损坏或使用不安全。他们中的大多数人都有这些迹象,例如误解密钥和 IV,现在从密钥中知道密码(使用 UTF-8 作为密钥也是愚蠢的,编码可能会将字符编码为多个字节)感谢 dnault 指出它们.现在开始学习加密,不要从互联网上抓取任何随机代码来执行加密。
-
顺便说一句,我喜欢上面代码中的异常处理。错误?不,
null! -
@owlstead:您会推荐哪个字符集作为密钥?
-
我相信 owlstead 关于字符集的观点是,当将字符串转换为字节数组时,字符和字节之间不一定存在 1:1 的对应关系。在 UTF-8 中,单个字符最多可以使用 4 个字节进行编码,因此对具有 16 个字符的任意字符串调用 getBytes("UTF-8") 不能保证返回长度为 16 的数组。从密码生成密钥是使用像 PBKDF2 这样的算法。
标签: java encryption aes