Files
Logan.Li b0b611eee2
CI / backend (push) Canceled after 0s
refactor(payment): 支付配置接入统一 secretbox 信封加密
- 丢弃支付模块自带的 PAYMENT_SECRET_KEY/JWT_SECRET 派生双密钥体系,
  EncryptSecret/DecryptSecret 直接走 internal/secretbox(OPSLIC_MASTER_KEY)
- 全站只有一把主密钥:Waffo 私钥、节点 shared_key、支付 APIv3 密钥/应用私钥同格式同前缀
- 测试改由 TestMain 装载 secretbox 主密钥,密文前缀统一引用 secretbox.Prefix
- .env.example 移除 PAYMENT_SECRET_KEY,改为说明复用 OPSLIC_MASTER_KEY
2026-11-01 06:03:24 +08:00

115 lines
3.4 KiB
Go
Raw Permalink 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 payment
import (
"backend/internal/secretbox"
"os"
"strings"
"testing"
)
// TestMain 固定测试用加密主密钥并装载信封加密(全站共用 OPSLIC_MASTER_KEY) // Logan.Li
func TestMain(m *testing.M) {
os.Setenv(EnvPaymentMasterKey, "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
os.Setenv("PAYMENT_CERT_DIR", os.TempDir()+"/opsx-licence-test-certs")
if err := secretbox.LoadMasterKey(); err != nil {
panic(err)
}
os.Exit(m.Run())
}
// TestEncryptDecryptRoundTrip 验证 AES-GCM 加解密与密文格式 // Logan.Li
func TestEncryptDecryptRoundTrip(t *testing.T) {
plain := "wx-api-v3-key-32-bytes-example!!"
enc, err := EncryptSecret(plain)
if err != nil {
t.Fatalf("加密失败: %v", err)
}
if !strings.HasPrefix(enc, secretbox.Prefix) {
t.Fatalf("密文缺少前缀: %s", enc)
}
if strings.Contains(enc, plain) {
t.Fatalf("密文中出现了明文")
}
got, err := DecryptSecret(enc)
if err != nil {
t.Fatalf("解密失败: %v", err)
}
if got != plain {
t.Fatalf("解密结果不一致: %q", got)
}
// 同一明文两次加密应产生不同密文(随机 nonce) // Logan.Li
enc2, _ := EncryptSecret(plain)
if enc == enc2 {
t.Fatalf("两次加密结果相同,nonce 未随机化")
}
}
// TestEncryptSecretEmpty 空值不应产生密文 // Logan.Li
func TestEncryptSecretEmpty(t *testing.T) {
enc, err := EncryptSecret(" ")
if err != nil || enc != "" {
t.Fatalf("空值加密应返回空串,得到 %q err=%v", enc, err)
}
if v, err := DecryptSecret(""); err != nil || v != "" {
t.Fatalf("空密文应返回空串,得到 %q err=%v", v, err)
}
}
// TestDecryptTampered 篡改密文必须解密失败 // Logan.Li
func TestDecryptTampered(t *testing.T) {
enc, _ := EncryptSecret("secret-value")
tampered := enc[:len(enc)-4] + "AAAA"
if _, err := DecryptSecret(tampered); err == nil {
t.Fatalf("篡改后的密文不应解密成功")
}
}
// TestMaskTail 脱敏仅保留末位 // Logan.Li
func TestMaskTail(t *testing.T) {
masked := MaskTail("0123456789abcdef0123456789abcdef", 4, 32)
if !strings.HasSuffix(masked, "cdef") {
t.Fatalf("脱敏结果应保留后 4 位: %s", masked)
}
if len([]rune(masked)) != 32 {
t.Fatalf("脱敏长度应为 32: %d", len([]rune(masked)))
}
if MaskTail("", 4, 32) != "" {
t.Fatalf("空值脱敏应为空串")
}
}
// TestPayMethods 支付方式校验/去重与展示解析 // Logan.Li
func TestPayMethods(t *testing.T) {
got, err := normalizePayMethods([]string{"native", " h5 ", "native", "JSAPI"})
if err != nil {
t.Fatalf("合法支付方式不应报错: %v", err)
}
want := []string{"native", "h5", "jsapi"}
if len(got) != len(want) {
t.Fatalf("解析结果数量不符: %v", got)
}
for i := range want {
if got[i] != want[i] {
t.Fatalf("解析结果不符: %v", got)
}
}
if _, err := normalizePayMethods([]string{"alipay"}); err == nil {
t.Fatalf("非法支付方式应报错")
}
if _, err := normalizePayMethods(nil); err == nil {
t.Fatalf("空支付方式应报错")
}
if def := splitPayMethods(""); len(def) != 1 || def[0] != "native" {
t.Fatalf("空串展示应回退 native: %v", def)
}
}
// TestNormalizePEM 裸 base64 自动补 PEM 头 // Logan.Li
func TestNormalizePEM(t *testing.T) {
out := NormalizePEM("QUJDREVGRw==", "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")
if !strings.HasPrefix(out, "-----BEGIN PUBLIC KEY-----") || !strings.Contains(out, "QUJDREVGRw==") {
t.Fatalf("PEM 补全失败: %s", out)
}
}