将PBKDF2盐重新用作IV的AES / GCM:危险吗? [英] Reusing PBKDF2 salt for AES/GCM as IV: dangerous?

查看:217
本文介绍了将PBKDF2盐重新用作IV的AES / GCM:危险吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一种加密实用程序类,可将其重用于常见操作。

I'm developing an encryption utility class to be reused for common operations.

一种非常常见的情况是使用用户提供的密码来加密纯文本。 br />
在这种情况下,我使用PBKDF2派生有效的AES密钥,然后在GCM模式下使用它来加密明文。

A very common case is to encrypt a plaintext with a user-provided password.
In this case, I'm using PBKDF2 to derive a valid AES key, then use it in GCM mode to encrypt the plaintext.

有些代码:

// IV_LEN = 96
// ITERATIONS = 1000 ~ 4000
// KEY_LEN = 128 ~ 256
// TAG_LEN = 128
public static String encrypt(byte[] plain, char[] password) throws GeneralSecurityException
{
    SecureRandom rng = SecureRandom.getInstanceStrong();
    byte[] iv = new byte[IV_LEN / 8];
    rng.nextBytes(iv);

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
    SecretKey derivedKey = factory.generateSecret(new PBEKeySpec(password, iv, ITERATIONS, KEY_LEN));
    SecretKey secretKey = new SecretKeySpec(derivedKey.getEncoded(), "AES");

    Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
    c.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(TAG_LEN, iv));

    byte[] encrypted = c.doFinal(plain);

    Encoder encoder = Base64.getUrlEncoder().withoutPadding();

    return encoder.encodeToString(iv) + ":" + encoder.encodeToString(encrypted);
}

当前,我也在使用PBKDF2盐(96位-SecureRandom)作为AES / GCM加密的IV。

Currently, I'm using the PBKDF2 salt (96 bit - SecureRandom) also as the IV for AES/GCM encryption.

salt和IV都可以公开使用,但是它们不应重复使用。

Both the salt and IV can be public, but they shouldn't be reused.

是否应该理解它们不应该在相同的功能/服务/算法中重复使用,还是不应该在任何地方重复使用?

Is it to be understood that they shouldn't be reused within the same Feature/Service/Algorithm, or that they shouldn't be reused anywhere?

很容易修改此方法以生成不同的盐和IV,但是有这样做的理由吗?

It's very easy to modify this method to generate different salt and IV, but is there a reason to do it?

谢谢

推荐答案

请注意,只要更改盐和因此得到的密钥,就可能不需要重新生成随机IV。如果每次(重新)加密时都没有更改盐,那么您要做需要单独的IV,否则您可能会将信息泄漏给对手。

Note that you may not need to re-generate a random IV as long as you change the salt and therefore the resulting key. If you do not change the salt each time you (re-)encrypt then you do need a separate IV or you may leak information to an adversary.

您可以将盐和IV保持相同。但是通常更容易从密码和盐中导出IV和密钥。如果您将PBKDF2与SHA-512哈希一起使用,这很容易:只需从生成的哈希中获取128、192或256位AES密钥,然后再将另外128位作为IV并使用。

You can keep the salt and IV the same. But it is generally easier to derive the IV together with the key from the password and salt. If you use PBKDF2 with a SHA-512 hash this is easy: just take 128, 192 or 256 bits of AES key from the resulting hash and then take another 128 subsequent bits as IV and use that.

如果需要多个键或使用较小的哈希,则可能需要从PBKDF2的结果派生更多键。在这种情况下,最好将PBKDF2的结果标记为主密钥,并从中进行N个密钥派生,每个密钥派生一个,对IV派生一个。您可以使用例如为此,Bouncy Castle有一个实现的HKDF(我提供了其原始源代码)。

If you need multiple keys or if you use a smaller hash then you may need to derive more keys from the result of PBKDF2. In that case it is best to mark the result of PBKDF2 as a master secret and perform N key derivations from it, one for each key and one for the IV. You could use e.g. HKDF for this, which Bouncy Castle has an implementation of (for which I provided the initial source code).

这篇关于将PBKDF2盐重新用作IV的AES / GCM:危险吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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