以下是使用 Argon2 算法的 Java 实现,用于安全密码哈希存储。Argon2 是密码哈希竞赛(PHC)的获胜者,被公认为当前最安全的密码哈希算法之一。
1. 添加依赖
首先,在 pom.xml
中添加 Bouncy Castle 或 Argon2 JVM 支持:
选项1:Bouncy Castle(推荐)
1 2 3 4 5 6
| <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency>
|
选项2:Argon2 JVM
1 2 3 4 5 6
| <dependency> <groupId>de.mkammerer</groupId> <artifactId>argon2-jvm</artifactId> <version>2.11</version> </dependency>
|
2. 完整代码实现(基于 Bouncy Castle)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| import org.bouncycastle.crypto.generators.Argon2BytesGenerator; import org.bouncycastle.crypto.params.Argon2Parameters; import java.security.SecureRandom; import java.util.Base64;
public class Argon2PasswordHasher {
private static final int ITERATIONS = 10; private static final int MEMORY = 65536; private static final int PARALLELISM = 1; private static final int SALT_LENGTH = 16; private static final int HASH_LENGTH = 32;
public static String hashPassword(String password) { byte[] salt = generateSalt(SALT_LENGTH);
Argon2Parameters.Builder builder = new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id) .withSalt(salt) .withIterations(ITERATIONS) .withMemoryAsKB(MEMORY) .withParallelism(PARALLELISM);
Argon2BytesGenerator generator = new Argon2BytesGenerator(); generator.init(builder.build()); byte[] hash = new byte[HASH_LENGTH]; generator.generateBytes(password.toCharArray(), hash);
return Base64.getEncoder().encodeToString(salt) + ":" + Base64.getEncoder().encodeToString(hash); }
public static boolean verifyPassword(String inputPassword, String storedHash) { String[] parts = storedHash.split(":"); byte[] salt = Base64.getDecoder().decode(parts[0]); byte[] originalHash = Base64.getDecoder().decode(parts[1]);
Argon2Parameters.Builder builder = new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id) .withSalt(salt) .withIterations(ITERATIONS) .withMemoryAsKB(MEMORY) .withParallelism(PARALLELISM);
Argon2BytesGenerator generator = new Argon2BytesGenerator(); generator.init(builder.build()); byte[] newHash = new byte[HASH_LENGTH]; generator.generateBytes(inputPassword.toCharArray(), newHash);
return MessageDigest.isEqual(originalHash, newHash); }
private static byte[] generateSalt(int length) { SecureRandom random = new SecureRandom(); byte[] salt = new byte[length]; random.nextBytes(salt); return salt; }
public static void main(String[] args) { String password = "MySecurePassword123!";
String hashedPassword = hashPassword(password); System.out.println("Hashed Password: " + hashedPassword);
boolean isValid = verifyPassword(password, hashedPassword); System.out.println("Password Valid: " + isValid);
isValid = verifyPassword("WrongPassword", hashedPassword); System.out.println("Wrong Password Valid: " + isValid); } }
|
3. 关键参数说明
参数 |
推荐值 |
作用 |
ITERATIONS |
10-20 |
增加计算时间,防御暴力破解 |
MEMORY |
64MB-1GB (65536 KB) |
增加内存消耗,防御GPU/ASIC攻击 |
PARALLELISM |
1-2 |
并行线程数(通常1即可) |
SALT_LENGTH |
16字节 |
确保每个密码哈希唯一 |
HASH_LENGTH |
32字节 |
输出哈希长度(与SHA-256一致) |
4. 为什么选择 Argon2?
- 抗GPU/ASIC:内存密集型设计,显著增加硬件攻击成本。
- 灵活配置:可调整时间/内存/线程参数,适应不同硬件。
- PHC获胜者:学术界和工业界公认的最安全密码哈希算法。
5. 注意事项
• 参数调优:根据服务器性能调整 ITERATIONS
和 MEMORY
(目标:哈希耗时约0.5-1秒)。
• 密码编码:建议明确指定字符集(如 password.getBytes(StandardCharsets.UTF_8)
)。
• 依赖更新:定期检查 Bouncy Castle 的安全公告。
6. 性能对比(示例)
算法 |
哈希耗时(1核CPU) |
抗GPU攻击能力 |
SHA-256 |
0.01ms |
❌ |
PBKDF2 |
100ms |
⚠️中等 |
Argon2 |
500ms |
✅最强 |
以上实现可直接用于生产环境,如需进一步强化,可结合加密(如AES)存储盐值。