代码之家  ›  专栏  ›  技术社区  ›  sudoExclamationExclamation

在数据库中存储时,我可以删除Argon2中密码哈希的前缀吗?

  •  0
  • sudoExclamationExclamation  · 技术社区  · 9 月前

    我使用Rust中的Argon2库进行密码哈希:

    https://docs.rs/argon2/latest/argon2/

    let salt = SaltString::generate(&mut OsRng);
    let argon2 = Argon2::default();
    let password_bytes = form.password.as_bytes();
    let password_hash = argon2.hash_password(&password_bytes, &salt).unwrap().to_string();
    
    println!("password_hash: {}",password_hash);
    
    let parsed_hash = PasswordHash::new(&password_hash).unwrap();
    if Argon2::default().verify_password(&password_bytes, &parsed_hash).is_ok() {
        println!("Valid!");
    }
    

    这个 password_hash 生成的内容如下:

    $argon2id$v=19$m=19456,t=2,p=1$UWyFFxDMETxLo1q7BFjIEQ$i3MwCW0H7fZjFG7hMwKAPZgWs4hjo/foEUCwLsqp9uY
    

    它似乎总是有前缀 $argon2id$v=19$m=19456,t=2,p=1$

    1. 在将前缀存储到数据库中之前,我可以删除它以节省空间吗?然后在验证之前对其进行硬编码以添加它?

    2. 这些东西是什么意思?

    3. 它总是一样的吗?

    1 回复  |  直到 9 月前
        1
  •  5
  •   IMSoP    9 月前

    现代密码哈希算法包含“成本参数”,这些参数以性能与安全性进行权衡——简单地说,你希望验证哈希值 太慢了 让攻击者尝试许多可能的密码,但是 足够快 合法用户不会认为你的应用程序坏了。

    为了在提供正确密码时生成匹配的哈希,您需要知道用于生成存储哈希的确切参数。正如你所说,你 能够 对这些参数进行硬编码,但这意味着 你永远无法改变它们 -特别是,随着计算机速度的加快,你希望你的哈希值变慢。

    因此,常见的做法是将使用的参数与每个哈希一起存储;那么,如果你把它们换成 哈希,你仍然可以 验证 旧哈希。一些库还允许您在用户登录时检查存储的哈希是否使用最新的参数值——只要您有正确的密码,就可以保存一个新的、更安全的哈希。

    同样,哈希算法有时会被发现被破坏,或者只是变得太容易被攻击者暴力破解。在这一点上,你可能想从Argon2换成完全不同的东西。同样,您需要知道哪些存储的哈希值正在使用Argon2,哪些正在使用新算法,因此常见的做法是在哈希值的开头指明使用的算法。

    对于Argon2,这些参数的格式实际上是已发布标准的一部分,因此 全部的 Argon2的实现将生成并期望这些精确的前缀。当你 能够 剥去它们,这样做真的没有什么好处,反而会损失很多。

    至于实际参数是什么 意思是 ,您可以在链接的Rust文档中,特别是在 the argon2::Params struct :

    • m_cost :内存大小为1 KiB块。之间 8*p_cost (2^32)-1 .
    • t_cost :迭代次数。之间 1 (2^32)-1
    • p_cost :平行度。之间 1. (2^24)-1 .