75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
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)
|
||
}
|
||
}
|