Files
pure-note/internal/auth/auth_test.go
T
wangairnan ba7d5dd01f fix(auth): VerifyPassword 校验 PHC 参数上下界
t/p=0 会使 argon2.IDKey panic、m 超大可 OOM;越界一律返回 false(round2 P2-8),补畸形参数用例。
2026-09-08 17:32:52 +08:00

75 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package auth
import "testing"
func TestPasswordHashRoundtrip(t *testing.T) {
hash, err := HashPassword("correct-horse-12")
if err != nil {
t.Fatal(err)
}
// PHC 串格式与参数(§7.3-1)
if len(hash) < len("$argon2id$v=19$m=19456,t=2,p=1$") ||
hash[:len("$argon2id$v=19$m=19456,t=2,p=1$")] != "$argon2id$v=19$m=19456,t=2,p=1$" {
t.Errorf("PHC 前缀/参数错误: %s", hash)
}
if !VerifyPassword(hash, "correct-horse-12") {
t.Error("正确口令应通过校验")
}
if VerifyPassword(hash, "wrong-password") {
t.Error("错误口令不应通过")
}
// 盐随机:同口令两次哈希不同
hash2, _ := HashPassword("correct-horse-12")
if hash == hash2 {
t.Error("同口令两次哈希应不同(随机盐)")
}
// 非法串安全返回 false
for _, bad := range []string{"", "$argon2id$", "$bcrypt$x$y$z", "$argon2id$v=19$m=1,t=1,p=1$!!$!!"} {
if VerifyPassword(bad, "x") {
t.Errorf("非法串 %q 不应通过", bad)
}
}
}
// TestVerifyPasswordMalformedParams 畸形 PHC 参数安全返回 false:
// t/p=0 会使 argon2.IDKey panic、m 巨大会 OOM(评审 round2 P2-8)。
func TestVerifyPasswordMalformedParams(t *testing.T) {
salt := "AAAAAAAAAAAAAAAAAAAAAA" // 16 字节 base64(raw std)
hash := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // 32 字节
bad := []string{
"$argon2id$v=19$m=19456,t=0,p=1$" + salt + "$" + hash,
"$argon2id$v=19$m=19456,t=2,p=0$" + salt + "$" + hash,
"$argon2id$v=19$m=999999999,t=2,p=1$" + salt + "$" + hash,
"$argon2id$v=19$m=19456,t=999,p=1$" + salt + "$" + hash,
"$argon2id$v=19$m=19456,t=2,p=99$" + salt + "$" + hash,
"$argon2id$v=19$m=19456,t=2,p=1$" + salt + "$AAAA", // 哈希长度异常
}
for _, h := range bad {
if VerifyPassword(h, "x") {
t.Errorf("畸形参数不应通过: %s", h)
}
}
}
func TestTokenAndStrength(t *testing.T) {
tok, err := NewToken()
if err != nil {
t.Fatal(err)
}
if len(tok) != 43 {
t.Errorf("256bit base64url token 应为 43 字符,实际 %d", len(tok))
}
if HashToken(tok) == tok {
t.Error("token 摘要不应等于明文")
}
if HashToken(tok) != HashToken(tok) {
t.Error("摘要应确定")
}
if err := CheckPasswordStrength("short12"); err == nil {
t.Error("弱口令应被拒绝")
}
if err := CheckPasswordStrength("strong-enough-12"); err != nil {
t.Errorf("合格口令不应被拒绝: %v", err)
}
}