默认情况下,当您加密时 - 您的密码将生成随机IV。解密该数据时,必须准确使用该特定 IV。
好消息是,IV不是一件秘密的事情 - 你可以把它存储在公共场合。主要思想是为每个加密 - 解密操作保持不同。
大多数时候,您需要加密 - 解密各种数据,并且为每个数据存储每个IV是一种痛苦。这就是为什么IV通常与加密数据一起存储在单个字符串中,作为固定大小的前缀。因此,当您解密字符串时 - 您肯定知道前16个字节(在我的情况下)是您的IV,其余字节 - 是加密数据,您需要解密它。
您的有效负载(用于存储或发送)将具有以下结构:
[{IV fixed length not encrypted}{encrypted data with secret key}]
让我分享我的加密和解密方法,我使用的是AES,256位密钥,16位IV,CBC模式和PKCS7Padding。正如Justin King-Lacroix上面所说,你最好使用GCM,CCM或EAX块模式。不要使用欧洲央行!
方法的结果是安全的,可以存储在DB中或发送到任何地方。encrypt()
请注意一个可以使用自定义IV的注释 - 只需将新的SecureRandom()替换为新的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());//new IvParameterSpec(getIV()) - if you want custom IV
//encrypted data:
byte[] encryptedBytes = encryptCipher.doFinal(data.getBytes("UTF-8"));
//take IV from this cipher
byte[] iv = encryptCipher.getIV();
//append Initiation Vector as a prefix to use it during decryption:
byte[] combinedPayload = new byte[iv.length + encryptedBytes.length];
//populate payload with prefix IV and encrypted data
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 {
//separate prefix with IV from the rest of encrypted data
byte[] encryptedPayload = Base64.decode(encryptedString, Base64.DEFAULT);
byte[] iv = new byte[16];
byte[] encryptedBytes = new byte[encryptedPayload.length - iv.length];
//populate iv with bytes:
System.arraycopy(encryptedPayload, 0, iv, 0, 16);
//populate encryptedBytes with bytes:
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;
}
希望这有帮助。