AES 256解密-IV是否可以安全共享? [英] AES 256 decryption - Is IV safe to share?

查看:166
本文介绍了AES 256解密-IV是否可以安全共享?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照此问题及其答案,我正在创建给定密码字符串的应用程序将转换纯文本并将其密文,生成的盐和初始化向量存储在文本文件中。



在以下代码中:

 公共字符串解密(CryptGroup cp)引发异常{
字符串明文= null;
SecretKeyFactory factory = SecretKeyFactory.getInstance( PBKDF2WithHmacSHA1);
KeySpec spec =新的PBEKeySpec(密码,cp.getSalt(),ITERATIONS,KEY_SIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), AES);

密码密码= Cipher.getInstance( AES / CBC / PKCS5Padding);
cipher.init(Cipher.DECRYPT_MODE,秘密,新的IvParameterSpec(cp.getIv()));
plaintext = new String(cipher.doFinal(cp.getCipher()), UTF-8);

返回纯文本;
}

公共CryptGroup crypto(String plainText)引发异常{
byte [] salt = generateSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance( PBKDF2WithHmacSHA1);
KeySpec spec =新的PBEKeySpec(密码,盐,ITERATIONS,KEY_SIZE);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), AES);

密码密码= Cipher.getInstance( AES / CBC / PKCS5Padding);
cipher.init(Cipher.ENCRYPT_MODE,秘密);
AlgorithmParameters params = cipher.getParameters();
byte [] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte [] ciphertext = cipher.doFinal(plainText.getBytes( UTF-8));

返回新的CryptGroup(密文,盐,iv);
}

CryptGroup对象包含这3个参数(密文,salt,iv:字节数组)



存储初始化向量安全吗?



该问题的答案明确指出,盐不必是秘密的,显然也可以使用密文,但是iv参数呢? p>

编辑
如果共享不安全,是否可以仅从盐中提取原始静脉注射?

解决方案

是的,IV可以是公共信息。只要您从未两次使用键和IV的组合,就可以将计算用作IV。换句话说,只要您为每次加密更改盐值,您就应该只能共享盐值。



此外,对于CBC,要求IV对于攻击者来说看起来像是随机的,尤其是当用于同一密钥时。因此,通常的方案是将PBKDF2的某些输出用作IV数据。



这有一些缺点,因为如果您请求160位以上的信息,PBKDF2将使用更多的回合(对于SHA1)。因此,您可以将PBKDF2的输出和一个计数器(密钥为0,IV为1)连接起来,并使用例如SHA256通过使用哈希的最左边的字节来生成密钥和IV。或者,如果您觉得冒险甚至更冒险,请使用HKDK之类的KBKDF。



您还可以使用其他哈希,例如SHA- 512,以创建更大的输出并将其拆分以获取键和IV,但请注意,此类功能可能并非在所有地方都可用。 Java 8应该具有 PBKDF2WithHmacSHA512 (对于 SecretKeyFactory )。


Following on this question and its answer, I am creating an application that given a password string, will convert a plaintext and store its ciphertext, the salt generated and the initialization vector in a text file.

In the following code :

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);
}

The CryptGroup object contains those 3 parameters (ciphertext, salt, iv : byte arrays for that matter).

Is it safe to store the initialization vector?

The answer in that question clearly states that the salt doesn't need to be secret, obviously the ciphertext can be also available, but what about the iv parameter?

Edit If it is not safe to share, is it possible to retrieve the original iv from the salt alone?

解决方案

Yes, IV's can be public information. You can use a calculation as IV, as long as you never use the combination of key and IV twice. In other words, you should be able to share just the salt, as long as you change the salt for each encryption.

Furthermore, for CBC it is required that IV "looks like random" to an attacker, especially when used for the same key. So a usual scheme is to use some output of PBKDF2 as IV data. That output of PBKDF2 should not be used to create the key!

This has some drawbacks as PBKDF2 will use many more rounds if you request more than 160 bits of information (for SHA1). So you may concatenate the output of PBKDF2 and a counter (0 for the key, 1 for the IV) and use e.g. SHA256 to generate key and IV by using the leftmost bytes of the hash. Or, if you are feeling even more adventurous, use a KBKDF such as HKDF.

You could also use a different hash such as SHA-512 to create a larger output and split it to get a key and IV, but beware that such a function may not be available everywhere. Java 8 should have "PBKDF2WithHmacSHA512" though (for the SecretKeyFactory).

这篇关于AES 256解密-IV是否可以安全共享?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆