2025-10-07 11:48:29 +08:00
|
|
|
|
package crypto
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"testing"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// TestPasswordHash 测试密码加密功能
|
|
|
|
|
|
func TestPasswordHash(t *testing.T) {
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
|
|
name string
|
|
|
|
|
|
password string
|
|
|
|
|
|
cost int
|
|
|
|
|
|
wantErr bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "默认cost加密",
|
|
|
|
|
|
password: "123456",
|
|
|
|
|
|
cost: 0, // 使用默认cost
|
|
|
|
|
|
wantErr: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "自定义cost加密",
|
|
|
|
|
|
password: "admin123",
|
|
|
|
|
|
cost: 12,
|
|
|
|
|
|
wantErr: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "空密码",
|
|
|
|
|
|
password: "",
|
|
|
|
|
|
cost: 10,
|
|
|
|
|
|
wantErr: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "复杂密码",
|
|
|
|
|
|
password: "MyP@ssw0rd!2024",
|
|
|
|
|
|
cost: 11,
|
|
|
|
|
|
wantErr: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
|
var hash string
|
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
|
|
if tc.cost > 0 {
|
|
|
|
|
|
hash, err = PasswordHash(tc.password, tc.cost)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
hash, err = PasswordHash(tc.password)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
|
if err == nil {
|
|
|
|
|
|
t.Errorf("PasswordHash() 期望出错,但没有错误")
|
|
|
|
|
|
}
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
t.Errorf("PasswordHash() 出现错误 = %v", err)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if hash == "" {
|
|
|
|
|
|
t.Errorf("PasswordHash() 返回空字符串")
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证生成的hash长度合理(bcrypt hash通常是60字符)
|
|
|
|
|
|
if len(hash) < 50 {
|
|
|
|
|
|
t.Errorf("PasswordHash() 返回的hash太短 = %d", len(hash))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证密码验证功能
|
|
|
|
|
|
if !PasswordVerify(tc.password, hash) {
|
|
|
|
|
|
t.Errorf("PasswordVerify() 验证失败,密码不匹配")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证错误密码
|
|
|
|
|
|
if PasswordVerify("wrongpassword", hash) {
|
|
|
|
|
|
t.Errorf("PasswordVerify() 应该验证失败,但验证成功了")
|
|
|
|
|
|
}
|
2025-10-11 18:35:12 +08:00
|
|
|
|
|
|
|
|
|
|
// 输出加密后的密码,便于人工检查
|
|
|
|
|
|
t.Logf("原始密码: %s, 加密后: %s", tc.password, hash)
|
2025-10-07 11:48:29 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TestPasswordVerify 测试密码验证功能
|
|
|
|
|
|
func TestPasswordVerify(t *testing.T) {
|
|
|
|
|
|
// 先生成一个已知的hash用于测试
|
|
|
|
|
|
testPassword := "123456"
|
|
|
|
|
|
testHash, err := PasswordHash(testPassword, 10)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
t.Fatalf("生成测试hash失败: %v", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
|
|
name string
|
|
|
|
|
|
password string
|
|
|
|
|
|
hash string
|
|
|
|
|
|
want bool
|
|
|
|
|
|
}{
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "正确密码",
|
|
|
|
|
|
password: testPassword,
|
|
|
|
|
|
hash: testHash,
|
|
|
|
|
|
want: true,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: "错误密码",
|
|
|
|
|
|
password: "wrongpassword",
|
|
|
|
|
|
hash: testHash,
|
|
|
|
|
|
want: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
|
got := PasswordVerify(tc.password, tc.hash)
|
|
|
|
|
|
if got != tc.want {
|
|
|
|
|
|
t.Errorf("PasswordVerify() = %v, want %v", got, tc.want)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TestGeneratePasswords 生成常用密码的hash值(用于实际使用)
|
|
|
|
|
|
func TestGeneratePasswords(t *testing.T) {
|
|
|
|
|
|
// 常用密码列表
|
|
|
|
|
|
passwords := []string{
|
|
|
|
|
|
"123456",
|
|
|
|
|
|
"admin123",
|
|
|
|
|
|
"password",
|
|
|
|
|
|
"root",
|
|
|
|
|
|
"test123",
|
|
|
|
|
|
"MyP@ssw0rd!2024",
|
|
|
|
|
|
"admin123.",
|
|
|
|
|
|
"123456789",
|
|
|
|
|
|
"qwerty",
|
|
|
|
|
|
"abc123",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Println("\n=== 生成密码Hash值 ===")
|
|
|
|
|
|
for i, password := range passwords {
|
|
|
|
|
|
hash, err := PasswordHash(password)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
t.Errorf("生成密码 %s 的hash失败: %v", password, err)
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fmt.Printf("%d. 密码: %-20s Hash: %s\n", i+1, password, hash)
|
|
|
|
|
|
|
|
|
|
|
|
// 验证生成的hash是否正确
|
|
|
|
|
|
if !PasswordVerify(password, hash) {
|
|
|
|
|
|
t.Errorf("验证密码 %s 失败", password)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
fmt.Println("=== 密码生成完成 ===")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// BenchmarkPasswordHash 性能测试
|
|
|
|
|
|
func BenchmarkPasswordHash(b *testing.B) {
|
|
|
|
|
|
password := "testpassword123"
|
|
|
|
|
|
|
|
|
|
|
|
b.Run("Cost10", func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
_, err := PasswordHash(password, 10)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
b.Fatal(err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
b.Run("Cost12", func(b *testing.B) {
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
_, err := PasswordHash(password, 12)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
b.Fatal(err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// BenchmarkPasswordVerify 验证性能测试
|
|
|
|
|
|
func BenchmarkPasswordVerify(b *testing.B) {
|
|
|
|
|
|
password := "testpassword123"
|
|
|
|
|
|
hash, _ := PasswordHash(password, 10)
|
|
|
|
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
|
|
PasswordVerify(password, hash)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|