package passwordutil import ( "crypto/sha256" "encoding/hex" "testing" ) // TestHashVerifyArgon2id 新算法:哈希后可校验,错误密码拒绝 func TestHashVerifyArgon2id(t *testing.T) { stored, err := Hash("Passw0rd@2026") if err != nil { t.Fatalf("Hash 失败: %v", err) } if !verifyArgon2id(stored, "Passw0rd@2026") { t.Fatal("正确密码应校验通过") } if verifyArgon2id(stored, "wrong-password") { t.Fatal("错误密码不应通过") } if NeedsRehash(stored) { t.Fatal("argon2id 不应需要重新哈希") } if AlgoOf(stored) != AlgoArgon2id { t.Fatalf("算法标识应为 argon2id,实际 %s", AlgoOf(stored)) } } // TestLegacyCompat 旧算法兼容:历史 salt$sha256 串仍可登录,且被标记为需要升级 func TestLegacyCompat(t *testing.T) { saltHex := "0123456789abcdef0123456789abcdef" sum := sha256.Sum256([]byte(saltHex + "oldpass")) legacy := saltHex + "$" + hex.EncodeToString(sum[:]) if !Verify(legacy, "oldpass") { t.Fatal("历史密码应校验通过(兼容)") } if Verify(legacy, "other") { t.Fatal("错误密码不应通过") } if !NeedsRehash(legacy) { t.Fatal("历史密码应标记为需要重新哈希") } if AlgoOf(legacy) != AlgoLegacy { t.Fatalf("算法标识应为 legacy,实际 %s", AlgoOf(legacy)) } } // TestDifferentSaltSamePassword 相同明文两次哈希结果必须不同(盐随机) func TestDifferentSaltSamePassword(t *testing.T) { a, _ := Hash("same-password") b, _ := Hash("same-password") if a == b { t.Fatal("相同明文两次哈希不应相同(盐必须随机)") } if !Verify(a, "same-password") || !Verify(b, "same-password") { t.Fatal("两份哈希都应能通过校验") } } // TestEmptyPassword 空密码边界 func TestEmptyPassword(t *testing.T) { if _, err := Hash(" "); err == nil { t.Fatal("空密码应返回错误") } if Verify("", "x") || Verify("x", "") { t.Fatal("空输入不应通过校验") } }