Files
XQKqueue/server/internal/security/security_test.go
2026-07-12 15:53:24 +08:00

80 lines
2.3 KiB
Go

package security
import (
"bytes"
"strings"
"testing"
)
func TestCipherRoundTripAndAADBinding(t *testing.T) {
cipher, err := NewCipher(bytes.Repeat([]byte{1}, 32), bytes.Repeat([]byte{2}, 32))
if err != nil {
t.Fatal(err)
}
ciphertext, nonce, err := cipher.Encrypt("+8613812345678", []byte("ticket:project-a:phone"))
if err != nil {
t.Fatal(err)
}
got, err := cipher.Decrypt(ciphertext, nonce, []byte("ticket:project-a:phone"))
if err != nil || got != "+8613812345678" {
t.Fatalf("round trip got %q, %v", got, err)
}
if _, err := cipher.Decrypt(ciphertext, nonce, []byte("ticket:project-b:phone")); err == nil {
t.Fatal("expected AAD mismatch to fail")
}
}
func TestCipherUsesUniqueNoncesAndStableHMAC(t *testing.T) {
cipher, _ := NewCipher(bytes.Repeat([]byte{1}, 32), bytes.Repeat([]byte{2}, 32))
one, nonceOne, _ := cipher.Encrypt("13812345678", nil)
two, nonceTwo, _ := cipher.Encrypt("13812345678", nil)
if bytes.Equal(nonceOne, nonceTwo) || bytes.Equal(one, two) {
t.Fatal("expected randomized encryption")
}
if cipher.Digest("13812345678") != cipher.Digest("13812345678") {
t.Fatal("expected stable HMAC digest")
}
}
func TestNormalizePhone(t *testing.T) {
got, err := NormalizePhone("+86 (138) 1234-5678")
if err != nil || got != "+8613812345678" {
t.Fatalf("got %q, %v", got, err)
}
for _, invalid := range []string{"123", "+01234567", "138-ABC-0000", strings.Repeat("1", 16)} {
if _, err := NormalizePhone(invalid); err == nil {
t.Fatalf("expected %q to fail", invalid)
}
}
}
func TestTokenHasHighEntropyAndHashes(t *testing.T) {
one, err := GenerateToken()
if err != nil {
t.Fatal(err)
}
two, _ := GenerateToken()
if one == two || len(one) < 40 {
t.Fatalf("unexpected tokens %q and %q", one, two)
}
if HashToken(one) == HashToken(two) || len(HashToken(one)) != 64 {
t.Fatal("unexpected token hashes")
}
}
func TestPasswordHash(t *testing.T) {
hash, err := HashPassword("correct horse battery staple")
if err != nil {
t.Fatal(err)
}
if !VerifyPassword(hash, "correct horse battery staple") || VerifyPassword(hash, "wrong password") {
t.Fatal("password verification mismatch")
}
if _, err := HashPassword("short"); err == nil {
t.Fatal("expected short password rejection")
}
if _, err := HashPassword("XQK123456"); err != nil {
t.Fatal("expected a nine-character password to satisfy the API policy")
}
}