194 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			194 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | 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() 应该验证失败,但验证成功了") | |||
|  | 			} | |||
|  | 		}) | |||
|  | 	} | |||
|  | } | |||
|  | 
 | |||
|  | // 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) | |||
|  | 	} | |||
|  | } |