对于不同性能的性能的硬件环境的密码hash的设计

web

本方案适合从32Mb极端的边缘设计到高性能服务器的密码安全hash的设计。 在安全性和性能之间寻找平衡并支持平衡迁移无感自动升级。

主要是解决随着GPU性能暴涨,传统的密码hash已经无法满足目前的安全需求。

#灵活可演进的密码哈希方案 (适用)

本方案通过算法版本化 (Versioning) 适配从 低性能设备到高性能服务器的跨度,兼顾性能、并发与安全。

#1. 数据库存储结构

  • password_hash: 完整的哈希字符串(含参数和有可能存在的盐)
  • password_type (uint8/int): 算法类型标识。 方便在代码里写 switch-case 分发给不同的加密库
    • 1: SHA256
    • 2: Bcrypt (标准模式,建议 Cost 10-12)。
    • 3: Argon2id (高安全模式,建议内存 64MB)。

#2. 系统运行逻辑

  • 全局配置: 管理员根据当前硬件算力(如 0.125 Core 或 32MB RAM)设置系统当前默认算法
  • 新用户/改密: 强制采用“当前默认算法”进行加密并记录 password_type
  • 登录校验: 不参考全局配置,直接读取该用户的 password_type 调用对应算法库进行验证。

#3. 平滑迁移与自动升级

  • 向下兼容: 允许数据库中同时存在三种算法的哈希数据,确保从高性能迁移到低性能设备时,老用户仍能登录。
    无感升级 (静默重哈希):

    • 当用户登录成功后,程序对比 user.password_type 与 `system.default_password_type。
    • 若用户算法版本不是系统配置,趁内存中持有明文密码,立即用新算法重算并覆盖数据库,实现数据随硬件升级而自动加固。

#4. 性能与安全平衡建议

  • 32MB 设备: 默认选 1。PBKDF2 内存占用近乎零,且比单次 SHA256 更能抵抗暴力破解。
  • 普通服务器: 默认选 2。Bcrypt 仅需 4KB 内存,能承受极高并发而不会导致 OOM。
  • 安全型服务器: 默认选 3。Argon2id 提供最强的抗 GPU 破解能力。

第一性原则:在低性能硬件可以降低密码安全性换取高性能,在高性能硬件可以牺牲算力和内存换取密码安全。

开发过程注意点

  • 数据库结构需要同时兼容sqlite和pgsql
  • 把密码相关的单独封装到一个crate ,yh-password-hash
  • 需要完善系统设置的可视化的性能配置模板,对其默认密码算法。
  • 新增配置项目
    • user_center.passwd_type # 当前默认算法:1-SHA256(PBKDF2), 2-Bcrypt, 3-Argon2
    • user_center.passwd_auto_upgrade #默认true 登录成功后是否自动升级到当前默认算法
    • user_center.passwd_Argon2_mem #默认32M 32768
    • user_center.passwd_Argon2_t #默认3
    • user_center.passwd_Argon2_p #默认1
    • user_center.passwd_bcrypt_cost #默认10
    • user_center.passwd_sha256_iterations #默认待定 - 默认迭代次数:建议 user_center.passwd_sha256_iterations 默认值为 310,000 (OWASP 最新推荐标准)。对于 64MB 的极低功耗路由,可以允许用户下调至 50,000 以换取秒开体验。
  • 因为 每种加密算法 需要记录的信息不同 ,Bcrypt 和 Argon2 有标准的 MCF/PHC 格式,但 PBKDF2 比较乱。为了兼容性,你需要规定一个存储标准:- 建议格式$pbkdf2-sha256$i=310000$salt$hash(仿照 Argon2 格式)。
  • password_hash 长度:在 PG 中用 TEXT,在 SQLite 中也用 TEXT。不要设定过短的 VARCHAR(255),Argon2 的完整字符串可能很长。
  • 原子更新:在执行“无感升级(静默重哈希)”时,代码必须在一个事务内完成,或者确保即使更新失败也不影响当前的登录会话(Session)
  • 性能保护 实现一个简单的 并发校验限制。例如:同时进行的 Argon2 校验任务不得超过 N 个,或者在校验失败后强制 sleep 几百毫秒。这在低功耗设备上是保命的
  • rust
    
    // 登录校验伪代码逻辑 伪代码 只是这个意思
    let user = db.get_user(username);
    let is_valid = match user.password_type {
      1 => pbkdf2::verify(input_password, user.password_hash),
      2 => bcrypt::verify(input_password, user.password_hash),
      3 => argon2::verify(input_password, user.password_hash),
      _ => return Error("Unknown algorithm"),
    };
    
    if is_valid && config.passwd_auto_upgrade && user.password_type != config.passwd_type {
        // 异步或同步执行:用新算法重算并 Update 数据库
        let new_hash = hash_with_config(input_password, config);
        db.update_password(user.id, new_hash, config.passwd_type);
    }

#最终补充 Checklist:

  • 错误处理:如果配置文件中的算法参数(如 Argon2 内存)超过了物理机剩余内存,系统应报明确的错误,尽量避免直接panic
  • 依赖库选型:建议使用 Rust 的 RustCrypto 组织下的仓库(如 argon2, bcrypt, pbkdf2),它们是纯 Rust 实现,跨平台支持(交叉编译到嵌入式设备)最好。
  • 常量定义:将算法 ID (1, 2, 3) 定义为 Enum,增强代码可读性。
  • 日志脱敏:在执行 passwd_auto_upgrade 时,记录一条 INFO 日志,但绝对禁止打印哈希值或明文。

评论