Mic*_*tti 2 java encryption cryptography pbkdf2 aes-gcm
我正在开发一个加密实用程序类,可将其重用于常见操作。
一种非常常见的情况是使用用户提供的密码来加密纯文本。
在这种情况下,我使用PBKDF2派生有效的AES密钥,然后在GCM模式下使用它来加密明文。
一些代码:
// 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);
}
Run Code Online (Sandbox Code Playgroud)
目前,我还将PBKDF2盐(96位-SecureRandom)也用作AES / GCM加密的IV。
salt和IV均可公开,但不应重复使用。
是否应该理解,不应在相同的功能/服务/算法中重用它们,或者不应该在任何地方重用它们?
修改此方法以生成不同的盐和IV很容易,但是有理由这样做吗?
谢谢
请注意,您只要更改盐并因此更改密钥,就可能不需要重新生成随机IV。如果每次(重新)加密时都没有更改盐,那么您确实需要单独的IV,否则您可能会将信息泄漏给对手。
您可以将盐和IV保持相同。但是通常更容易从密码和盐中导出IV和密钥。如果您将PBKDF2与SHA-512哈希一起使用,这很容易:只需从生成的哈希中获取128、192或256位AES密钥,然后再获取其他128位作为IV并使用它。
如果需要多个密钥,或者使用较小的哈希,则可能需要从PBKDF2的结果派生更多密钥。在这种情况下,最好将PBKDF2的结果标记为主密钥,并从中进行N个密钥派生,每个密钥派生一个,对IV派生一个。您可以为此使用例如HKDF,Bouncy Castle有一个实现(我为其提供了原始源代码)。
| 归档时间: |
|
| 查看次数: |
497 次 |
| 最近记录: |