Argon2案例

wen java案例 3

本文目录导读:

Argon2案例

  1. Python 实现案例
  2. Node.js 实现案例
  3. 实际应用场景案例
  4. 高级用法:密码过期和重新哈希
  5. 安全最佳实践
  6. 完整测试案例

我来为你提供Argon2密码哈希算法的完整使用案例,包含多种语言实现和最佳实践。

Python 实现案例

基本使用(推荐方式)

from argon2 import PasswordHasher
import time
# 创建PasswordHasher实例(使用默认参数)
ph = PasswordHasher()
def hash_password(password: str) -> str:
    """哈希密码"""
    start = time.time()
    hash_str = ph.hash(password)
    elapsed = time.time() - start
    print(f"哈希耗时: {elapsed:.3f}秒")
    return hash_str
def verify_password(hash_str: str, password: str) -> bool:
    """验证密码"""
    try:
        start = time.time()
        result = ph.verify(hash_str, password)
        elapsed = time.time() - start
        print(f"验证耗时: {elapsed:.3f}秒")
        return result
    except Exception as e:
        print(f"验证失败: {e}")
        return False
# 使用示例
password = "MySecurePassword123!"
print(f"原始密码: {password}")
# 哈希密码
hashed = hash_password(password)
print(f"哈希结果: {hashed}")
# 验证密码
print(f"\n验证正确密码: {verify_password(hashed, password)}")
print(f"验证错误密码: {verify_password(hashed, 'wrong_password')}")

自定义参数配置

from argon2 import PasswordHasher, Type
import time
# 自定义参数
ph = PasswordHasher(
    time_cost=3,          # 时间成本(迭代次数)
    memory_cost=65536,    # 内存成本(KB)
    parallelism=4,        # 并行度
    hash_len=32,          # 哈希长度
    salt_len=16,          # 盐长度
    type=Type.ID          # Argon2类型 (ID推荐)
)
def benchmark_parameters():
    """基准测试不同参数配置"""
    configs = [
        {"time_cost": 2, "memory_cost": 32768, "parallelism": 2},
        {"time_cost": 3, "memory_cost": 65536, "parallelism": 4},
        {"time_cost": 4, "memory_cost": 131072, "parallelism": 8},
    ]
    password = "BenchmarkTest123!"
    for i, config in enumerate(configs, 1):
        ph_test = PasswordHasher(**config)
        start = time.time()
        hashed = ph_test.hash(password)
        elapsed = time.time() - start
        print(f"配置 {i}: {config}")
        print(f"  耗时: {elapsed:.3f}秒")
        print(f"  结果长度: {len(hashed)}字符")
        print()

Node.js 实现案例

使用 argon2 库

const argon2 = require('argon2');
const { performance } = require('perf_hooks');
class PasswordHasher {
    constructor(options = {}) {
        this.options = {
            type: argon2.argon2id,  // 推荐使用 argon2id
            timeCost: 3,           // 时间成本
            memoryCost: 65536,     // 内存成本 (64MB)
            parallelism: 4,        // 并行度
            hashLength: 32,        // 哈希长度
            saltLength: 16,        // 盐长度
            ...options
        };
    }
    async hash(password) {
        const start = performance.now();
        const hash = await argon2.hash(password, this.options);
        const elapsed = (performance.now() - start) / 1000;
        console.log(`哈希耗时: ${elapsed.toFixed(3)}秒`);
        return hash;
    }
    async verify(hash, password) {
        try {
            const start = performance.now();
            const result = await argon2.verify(hash, password);
            const elapsed = (performance.now() - start) / 1000;
            console.log(`验证耗时: ${elapsed.toFixed(3)}秒`);
            return result;
        } catch (error) {
            console.error('验证失败:', error.message);
            return false;
        }
    }
}
// 使用示例
async function main() {
    const hasher = new PasswordHasher();
    const password = 'MySecurePassword123!';
    console.log(`原始密码: ${password}`);
    // 哈希密码
    const hashedPassword = await hasher.hash(password);
    console.log(`哈希结果: ${hashedPassword}`);
    // 验证密码
    console.log(`\n验证正确密码: ${await hasher.verify(hashedPassword, password)}`);
    console.log(`验证错误密码: ${await hasher.verify(hashedPassword, 'wrong')}`);
    // 性能测试
    console.log('\n--- 性能测试 ---');
    const times = [];
    for (let i = 0; i < 5; i++) {
        const start = performance.now();
        await hasher.hash(password);
        times.push((performance.now() - start) / 1000);
    }
    const avgTime = times.reduce((a, b) => a + b) / times.length;
    console.log(`平均耗时: ${avgTime.toFixed(3)}秒`);
}
main().catch(console.error);

实际应用场景案例

用户注册和登录系统

# user_auth.py
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
import json
import os
class UserAuthSystem:
    def __init__(self, password_file="users.json"):
        self.ph = PasswordHasher(
            time_cost=3,
            memory_cost=65536,
            parallelism=4,
            hash_len=32,
            salt_len=16
        )
        self.password_file = password_file
        self.users = self._load_users()
    def _load_users(self):
        """加载用户数据"""
        if os.path.exists(self.password_file):
            with open(self.password_file, 'r') as f:
                return json.load(f)
        return {}
    def _save_users(self):
        """保存用户数据"""
        with open(self.password_file, 'w') as f:
            json.dump(self.users, f, indent=2)
    def register(self, username: str, password: str) -> bool:
        """用户注册"""
        if username in self.users:
            print(f"用户 {username} 已存在")
            return False
        # 密码强度检查
        if len(password) < 8:
            print("密码长度至少8位")
            return False
        # 哈希密码
        hashed_password = self.ph.hash(password)
        # 存储用户信息
        self.users[username] = {
            "password_hash": hashed_password,
            "created_at": "2024-01-01",  # 实际应用使用datetime
            "failed_attempts": 0
        }
        self._save_users()
        print(f"用户 {username} 注册成功")
        return True
    def login(self, username: str, password: str) -> bool:
        """用户登录"""
        if username not in self.users:
            print(f"用户 {username} 不存在")
            return False
        user_data = self.users[username]
        # 检查失败次数(防止暴力破解)
        if user_data.get("failed_attempts", 0) >= 5:
            print("账户已锁定,请稍后重试")
            return False
        try:
            # 验证密码
            if self.ph.verify(user_data["password_hash"], password):
                # 重置失败次数
                user_data["failed_attempts"] = 0
                self._save_users()
                print(f"用户 {username} 登录成功")
                return True
            else:
                # 增加失败次数
                user_data["failed_attempts"] = user_data.get("failed_attempts", 0) + 1
                self._save_users()
                print("密码错误")
                return False
        except VerifyMismatchError:
            print("密码验证失败")
            return False
    def change_password(self, username: str, old_password: str, new_password: str) -> bool:
        """修改密码"""
        if not self.login(username, old_password):
            return False
        # 检查新密码强度
        if len(new_password) < 8:
            print("新密码长度至少8位")
            return False
        # 检查新旧密码是否相同
        if old_password == new_password:
            print("新密码不能与旧密码相同")
            return False
        # 更新密码
        self.users[username]["password_hash"] = self.ph.hash(new_password)
        self._save_users()
        print(f"用户 {username} 密码修改成功")
        return True
# 使用示例
def main():
    auth = UserAuthSystem()
    # 注册用户
    auth.register("alice", "SecurePass123!")
    auth.register("bob", "AnotherPass456!")
    # 登录测试
    print("\n--- 登录测试 ---")
    auth.login("alice", "SecurePass123!")  # 成功
    auth.login("alice", "wrong_password")  # 失败
    auth.login("unknown", "test")          # 用户不存在
    # 修改密码
    print("\n--- 修改密码 ---")
    auth.change_password("alice", "SecurePass123!", "NewSecurePass789!")
    # 使用新密码登录
    auth.login("alice", "NewSecurePass789!")
if __name__ == "__main__":
    main()

高级用法:密码过期和重新哈希

from argon2 import PasswordHasher
from argon2.exceptions import VerificationError, InvalidHashError
import time
from datetime import datetime, timedelta
class PasswordManager:
    def __init__(self):
        self.ph = PasswordHasher()
        # 密码过期时间(天)
        self.password_expiry_days = 90
        # 需要重新哈希的阈值(秒)
        self.rehash_threshold = 3.0
    def hash_with_metadata(self, password: str) -> dict:
        """哈希密码并添加元数据"""
        start = time.time()
        hashed = self.ph.hash(password)
        duration = time.time() - start
        return {
            "hash": hashed,
            "created_at": datetime.now().isoformat(),
            "hash_duration": duration,
            "hash_algorithm": "argon2id"
        }
    def verify_and_check(self, password_data: dict, password: str) -> dict:
        """验证密码并检查是否需要更新"""
        result = {
            "valid": False,
            "needs_rehash": False,
            "expired": False,
            "message": ""
        }
        try:
            # 验证密码
            start = time.time()
            valid = self.ph.verify(password_data["hash"], password)
            duration = time.time() - start
            if not valid:
                result["message"] = "密码错误"
                return result
            result["valid"] = True
            # 检查是否需要重新哈希(性能变化)
            if duration < self.rehash_threshold:
                result["needs_rehash"] = True
                result["message"] = "密码需要重新哈希以提高安全性"
            # 检查密码是否过期
            created_at = datetime.fromisoformat(password_data["created_at"])
            if datetime.now() - created_at > timedelta(days=self.password_expiry_days):
                result["expired"] = True
                result["message"] = "密码已过期,请更新密码"
            return result
        except (VerificationError, InvalidHashError) as e:
            result["message"] = f"验证失败: {str(e)}"
            return result
# 使用示例
def main():
    pm = PasswordManager()
    password = "MySecurePassword123!"
    # 哈希密码
    password_data = pm.hash_with_metadata(password)
    print(f"密码数据: {password_data}")
    # 验证密码
    result = pm.verify_and_check(password_data, password)
    print(f"\n验证结果: {result}")
    # 如果需要重新哈希
    if result["needs_rehash"]:
        print("\n重新哈希密码...")
        new_password_data = pm.hash_with_metadata(password)
        print(f"新密码数据: {new_password_data}")
if __name__ == "__main__":
    main()

安全最佳实践

推荐的参数设置

# 根据应用场景选择参数
# Web应用(推荐)
web_params = {
    "time_cost": 3,
    "memory_cost": 65536,  # 64MB
    "parallelism": 4,
    "hash_len": 32,
    "salt_len": 16,
    "type": Type.ID
}
# 高安全性场景
high_security_params = {
    "time_cost": 5,
    "memory_cost": 131072,  # 128MB
    "parallelism": 8,
    "hash_len": 64,
    "salt_len": 32,
    "type": Type.ID
}
# 移动设备(资源受限)
mobile_params = {
    "time_cost": 2,
    "memory_cost": 16384,  # 16MB
    "parallelism": 2,
    "hash_len": 32,
    "salt_len": 16,
    "type": Type.ID
}

安全检查清单

class SecurityAudit:
    """安全检查工具"""
    @staticmethod
    def test_hash_speed(hasher: PasswordHasher, iterations: int = 10) -> dict:
        """测试哈希速度"""
        password = "test_password_123!"
        times = []
        for _ in range(iterations):
            start = time.time()
            hasher.hash(password)
            times.append(time.time() - start)
        avg_time = sum(times) / len(times)
        return {
            "min_time": min(times),
            "max_time": max(times),
            "avg_time": avg_time,
            "recommendation": "good" if 0.5 < avg_time < 3 else "adjust"
        }
    @staticmethod
    def validate_current_hash(hashed: str) -> dict:
        """验证当前哈希配置是否安全"""
        try:
            # 解析哈希参数
            parts = hashed.split('$')
            params = parts[3]  # 参数部分
            m_value = int(params.split('m=')[1].split(',')[0])
            t_value = int(params.split('t=')[1].split(',')[0])
            p_value = int(params.split('p=')[1].split(',')[0])
            recommendation = []
            if m_value < 65536:
                recommendation.append(f"增加内存成本: {m_value} -> 65536")
            if t_value < 3:
                recommendation.append(f"增加时间成本: {t_value} -> 3")
            if p_value < 4:
                recommendation.append(f"增加并行度: {p_value} -> 4")
            return {
                "memory_cost": m_value,
                "time_cost": t_value,
                "parallelism": p_value,
                "is_secure": len(recommendation) == 0,
                "recommendations": recommendation
            }
        except Exception as e:
            return {
                "error": str(e),
                "is_secure": False
            }

完整测试案例

import unittest
from argon2 import PasswordHasher
class TestArgon2Hashing(unittest.TestCase):
    def setUp(self):
        self.ph = PasswordHasher()
    def test_basic_hashing(self):
        password = "TestPassword123!"
        hashed = self.ph.hash(password)
        # 验证哈希格式
        self.assertTrue(hashed.startswith("$argon2"))
        self.assertTrue(self.ph.verify(hashed, password))
    def test_wrong_password(self):
        hashed = self.ph.hash("correct_password")
        self.assertFalse(self.ph.verify(hashed, "wrong_password"))
    def test_different_salts(self):
        password = "SamePassword"
        hash1 = self.ph.hash(password)
        hash2 = self.ph.hash(password)
        # 每次哈希应该不同(因为有随机盐)
        self.assertNotEqual(hash1, hash2)
    def test_special_characters(self):
        passwords = [
            "!@#$%^&*()",
            "密码123",
            " \t\n",
            "a" * 100,  # 长密码
            "",         # 空密码
        ]
        for password in passwords:
            with self.subTest(password=password[:10]):
                hashed = self.ph.hash(password)
                self.assertTrue(self.ph.verify(hashed, password))
    def test_hash_length(self):
        password = "TestPassword"
        hashed = self.ph.hash(password)
        self.assertGreater(len(hashed), 60)
if __name__ == "__main__":
    unittest.main()

这些案例涵盖了Argon2的主要使用场景和最佳实践,根据你的具体需求选择合适的实现方式,并确保定期评估和更新安全参数。

抱歉,评论功能暂时关闭!