PBKDF2算法:一种基于密码的密钥派生算法
PBKDF2(Password-Based Key Derivation Function 2)是一种基于密码的密钥派生算法,它通过对密码进行多次哈希运算生成加密密钥,增强密码强度。PBKDF2主要用于以下场景:
- 密码存储:通过多次迭代和使用随机盐来增加破解难度。
- 密钥生成:为对称加密算法(如AES)生成安全的密钥。
工作原理
PBKDF2 接受如下参数:
- 密码:用户输入的原始密码。
- 盐值:为防止相同密码生成相同的密钥,PBKDF2 使用一个随机生成的盐。
- 迭代次数:PBKDF2算法会对密码和盐进行多次哈希运算,迭代次数越高,计算开销越大,安全性越高。
- 派生密钥的长度:输出密钥的长度,通常设置为128位、256位等。
算法核心为对密码和盐值多次执行哈希函数(如HMAC-SHA256),迭代次数和密钥长度决定了PBKDF2的性能与安全性。
PBKDF2的哈希过程示意如下:
D K = P B K D F 2 ( P , S , c , d k L e n ) DK = PBKDF2(P, S, c, dkLen) DK=PBKDF2(P,S,c,dkLen)
其中, D K DK DK 是派生密钥, P P P 是密码, S S S 是盐, c c c 是迭代次数, d k L e n dkLen dkLen 是派生密钥的期望长度。
Java中的PBKDF2示例
使用Java的 SecretKeyFactory
和 PBEKeySpec
类可以轻松实现 PBKDF2,例如使用 HMAC-SHA256 作为哈希函数。
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.SecureRandom;
import java.util.Base64;public class PBKDF2Example {private static final int ITERATIONS = 100000; // 迭代次数private static final int KEY_LENGTH = 256; // 密钥长度(位)private static final int SALT_LENGTH = 16; // 盐值长度(字节)/*** 生成随机盐值*/public static byte[] generateSalt() {byte[] salt = new byte[SALT_LENGTH];new SecureRandom().nextBytes(salt);return salt;}/*** 使用PBKDF2-HMAC-SHA256生成密钥*/public static String generatePBKDF2Key(char[] password, byte[] salt) throws Exception {PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");byte[] key = keyFactory.generateSecret(spec).getEncoded();return Base64.getEncoder().encodeToString(key);}public static void main(String[] args) {try {// 输入密码char[] password = "examplePassword".toCharArray();// 生成盐值byte[] salt = generateSalt();// 生成PBKDF2密钥String derivedKey = generatePBKDF2Key(password, salt);// 输出盐值和密钥System.out.println("Salt (Base64): " + Base64.getEncoder().encodeToString(salt));System.out.println("Derived Key (Base64): " + derivedKey);} catch (Exception e) {e.printStackTrace();}}
}
代码说明
- generateSalt():生成随机盐,确保每次生成的密钥是唯一的。
- generatePBKDF2Key():使用PBKDF2和HMAC-SHA256生成密钥,迭代次数为100,000,输出为256位密钥。
- Base64编码:以Base64格式输出盐值和密钥,便于存储和传输。
安全注意事项
- 随机盐:防止彩虹表攻击,确保每次派生出的密钥唯一。
- 足够的迭代次数:提高密码破解难度。
- 适当的密钥长度:通常建议为128位或更高,以适应不同应用场景。
PBKDF2广泛应用于密码存储、密钥管理和加密操作,是一种成熟且可靠的密钥派生方案。
SecretKeyFactory支持PBKDF2的算法实例
SecretKeyFactory
支持多种 PBKDF2
算法实例,常见的包括基于不同哈希函数的 PBKDF2
实例,如 PBKDF2WithHmacSHA1
、PBKDF2WithHmacSHA256
、PBKDF2WithHmacSHA512
,这些实例的主要区别在于使用的哈希算法不同。此外,某些加密库(如BouncyCastle)也支持国密(SM系列)算法与 PBKDF2
的结合。
以下是主要的 PBKDF2
算法实例及其区别:
1. PBKDF2WithHmacSHA1
- 哈希算法:SHA-1
- 安全性:SHA-1 已被认为不够安全,但在某些应用中仍然被使用,尤其是向后兼容性场景。
- 推荐性:不建议用于高安全性应用,因其哈希算法较弱。
2. PBKDF2WithHmacSHA256
- 哈希算法:SHA-256
- 安全性:SHA-256 是较为安全且常用的哈希算法,安全性较高,广泛应用于密码存储和密钥派生。
- 推荐性:推荐用于大多数应用,尤其是需要高强度安全保障的场景。
3. PBKDF2WithHmacSHA512
- 哈希算法:SHA-512
- 安全性:SHA-512 提供更强的安全性,哈希输出更长(512位),适合超高安全需求的应用。
- 推荐性:适合对安全性要求极高的应用,但由于输出长度较长,可能占用更多的存储空间。
4. PBKDF2WithHmacSHA384
- 哈希算法:SHA-384
- 安全性:SHA-384 的安全性介于 SHA-256 和 SHA-512 之间,输出较长,但没有像 SHA-512 那么大。
- 推荐性:适合需要中等以上安全性的场景。
5. PBKDF2WithHmacSHA224
- 哈希算法:SHA-224
- 安全性:SHA-224 是 SHA-256 的截短版,输出更短(224位)。虽然提供了一定的安全性,但一般不如 SHA-256 适合常规应用。
- 推荐性:适合低内存占用且不需超高安全性的场景。
6. PBKDF2WithHmacSM3(国密算法)
- 哈希算法:SM3
- 安全性:SM3 是中国国家商用密码算法,提供与 SHA-256 类似的安全性,输出为256位哈希值。
- 推荐性:在国密算法环境下使用,满足国密标准的加密和密钥派生需求,适用于中国境内的安全场景和相关法律法规的合规要求。
7. PBKDF2WithHmacMD5
- 哈希算法:MD5
- 安全性:MD5 由于已被破解,不推荐用于任何安全应用,尤其是涉及密码和敏感数据的场景。
- 推荐性:不推荐,MD5的安全性已被广泛质疑。
区别总结
- 安全性:PBKDF2 算法的安全性取决于所使用的哈希函数。较新和强大的哈希函数如
SHA-256
、SHA-512
和SM3
提供更高的安全性,而较老的如SHA-1
和MD5
由于已被破解或被认为脆弱,不再推荐使用。 - 国密支持:
PBKDF2WithHmacSM3
适用于国密算法标准,符合中国国家信息安全标准,在国密场景中,建议使用 SM3 算法结合 PBKDF2 以满足合规要求。
推荐的 PBKDF2 算法
- 全球通用应用:
PBKDF2WithHmacSHA256
或PBKDF2WithHmacSHA512
。 - 国密应用:
PBKDF2WithHmacSM3
。
这些实例在性能上可能略有不同,主要区别是哈希函数的安全性和输出长度。