默认情况下,当您加密时,您的密码会生成一个随机IV。当您解密该数据时,必须使用确切的IV。
好消息是,IV不是秘密,您可以将其存储在公共位置。主要思想是为每个加密-解密操作保持不同的IV。
大多数情况下,您需要加密-解密各种数据,并为每个数据存储每个IV很麻烦。这就是为什么IV通常会与加密数据一起存储在单个字符串中,作为固定大小的前缀,以便在解密字符串时,您确定前16个字节(在我的情况下)是IV,其余字节是加密数据,需要进行解密。
您的有效载荷(要存储或发送)将具有以下结构:
[{未加密的IV固定长度}{使用秘密密钥加密的数据}]
这里分享我的encrypt和decrypt方法,我使用AES、256位秘密密钥、16位IV、CBC模式和PKCS7Padding。正如Justin King-Lacroix上面所述,最好使用GCM、CCM或EAX块模式。不要使用ECB!encrypt() 方法的结果是安全的,并且可以随时存储在数据库中或发送到任何地方。
注意:您可以在注释中使用自定义IV-只需将new SecureRandom()替换为new IvParameterSpec(getIV())(您可以在此输入静态IV,但这强烈不推荐)。
private Key secretAes256Key
是具有秘密密钥的类字段,在构造函数中初始化。
private static final String AES_TRANSFORMATION_MODE = "AES/CBC/PKCS7Padding"
encrypt()
方法:
public String encrypt(String data) {
String encryptedText = "";
if (data == null || secretAes256Key == null)
return encryptedText;
}
try {
Cipher encryptCipher = Cipher.getInstance(AES_TRANSFORMATION_MODE);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretAes256Key, new SecureRandom());
byte[] encryptedBytes = encryptCipher.doFinal(data.getBytes("UTF-8"));
byte[] iv = encryptCipher.getIV();
byte[] combinedPayload = new byte[iv.length + encryptedBytes.length];
System.arraycopy(iv, 0, combinedPayload, 0, iv.length);
System.arraycopy(encryptedBytes, 0, combinedPayload, iv.length, encryptedBytes.length);
encryptedText = Base64.encodeToString(combinedPayload, Base64.DEFAULT);
} catch (NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException | UnsupportedEncodingException | InvalidKeyException e) {
e.printStackTrace();
}
return encryptedText;
}
这里是decrypt()
方法:
public String decrypt(String encryptedString) {
String decryptedText = "";
if (encryptedString == null || secretAes256Key == null)
return decryptedText;
}
try {
byte[] encryptedPayload = Base64.decode(encryptedString, Base64.DEFAULT);
byte[] iv = new byte[16];
byte[] encryptedBytes = new byte[encryptedPayload.length - iv.length];
System.arraycopy(encryptedPayload, 0, iv, 0, 16);
System.arraycopy(encryptedPayload, iv.length, encryptedBytes, 0, encryptedBytes.length);
Cipher decryptCipher = Cipher.getInstance(AES_TRANSFORMATION_MODE);
decryptCipher.init(Cipher.DECRYPT_MODE, secretAes256Key, new IvParameterSpec(iv));
byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);
decryptedText = new String(decryptedBytes);
} catch (NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
}
return decryptedText;
}
希望这可以帮助到你。
Hope this helps.
翻译后为:
希望这可以帮助到你。