关于this question及其答案,我正在创建一个给出密码字符串的应用程序,将转换明文并将其密文,生成的盐和初始化向量存储在文本文件中。
在以下代码中:
public String decrypt(CryptGroup cp) throws Exception {
String plaintext = null;
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, cp.getSalt(), ITERATIONS, KEY_SIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(cp.getIv()));
plaintext = new String(cipher.doFinal(cp.getCipher()), "UTF-8");
return plaintext;
}
public CryptGroup encrypt(String plainText) throws Exception {
byte[] salt = generateSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_SIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal(plainText.getBytes("UTF-8"));
return new CryptGroup(ciphertext, salt, iv);
}
CryptGroup对象包含这3个参数(密文,salt,iv:字节数组)。
存储初始化向量是否安全?
该问题的答案明确指出盐不需要保密,显然密文也可以使用,但iv参数怎么样?
修改 如果分享不安全,是否可以单独从盐中检索原始的静脉注射?
答案 0 :(得分:3)
是的,IV可以是公共信息。您可以将计算用作IV,只要您从不使用键和IV的组合两次。换句话说,只要您为每次加密更改salt ,就应该只能共享salt 。
此外,对于CBC,要求IV"看起来像随机的"对攻击者,特别是当用于相同的密钥时。因此,通常的方案是使用PBKDF2的一些输出作为IV数据。 PBKDF2的输出不应该用于创建密钥!
这有一些缺点,因为如果您请求超过160位的信息(对于SHA1),PBKDF2将使用更多轮次。因此,您可以连接PBKDF2的输出和计数器(0表示密钥,1表示IV)并使用例如SHA256通过使用散列的最左边的字节来生成密钥和IV。或者,如果您感觉更多冒险,请使用像HKDF这样的KBKDF。
您还可以使用不同的哈希值(例如SHA-512)来创建更大的输出并将其拆分以获得密钥和IV,但请注意,此类功能可能无法在任何地方使用。 Java 8应该有"PBKDF2WithHmacSHA512"
(对于SecretKeyFactory
)。