plugins/utils/osais/sign_test.go

124 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 osais
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"testing"
)
// 生成测试密钥对PKCS8 私钥 / PKIX 公钥Base64
func testKeyPair(t *testing.T) (priB64, pubB64 string) {
t.Helper()
pri, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("生成密钥失败: %v", err)
}
priDER, err := x509.MarshalPKCS8PrivateKey(pri)
if err != nil {
t.Fatalf("编码私钥失败: %v", err)
}
priB64 = base64.StdEncoding.EncodeToString(priDER)
pubDER, err := x509.MarshalPKIXPublicKey(&pri.PublicKey)
if err != nil {
t.Fatalf("编码公钥失败: %v", err)
}
pubB64 = base64.StdEncoding.EncodeToString(pubDER)
return priB64, pubB64
}
func TestSignVerify(t *testing.T) {
priB64, pubB64 := testKeyPair(t)
data := []byte("appid=1j0m408660091832&bizContent={\"bizUserId\":\"demo-user-001\"}&method=osais.wxbizpay.auth&timestamp=1504147887642&version=1.0")
sig, err := Sign(data, priB64)
if err != nil {
t.Fatalf("签名失败: %v", err)
}
ok, err := Verify(data, sig, pubB64)
if err != nil {
t.Fatalf("验签出错: %v", err)
}
if !ok {
t.Fatal("验签失败:签名不匹配")
}
// 篡改数据后验签必须失败
ok, _ = Verify([]byte(string(data[:len(data)-2])+"99"), sig, pubB64)
if ok {
t.Fatal("篡改数据后验签仍通过,不安全")
}
}
func TestVerifyPKCS1PublicKey(t *testing.T) {
// 兼容 PKCS#1 公钥格式对接方公钥为该格式mock 场景)
pri, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("生成密钥失败: %v", err)
}
priDER, _ := x509.MarshalPKCS8PrivateKey(pri)
priB64 := base64.StdEncoding.EncodeToString(priDER)
pubB64 := base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&pri.PublicKey))
data := []byte("code=0&data={}&msg=success")
sig, err := Sign(data, priB64)
if err != nil {
t.Fatalf("签名失败: %v", err)
}
ok, err := Verify(data, sig, pubB64)
if err != nil {
t.Fatalf("PKCS1 公钥验签出错: %v", err)
}
if !ok {
t.Fatal("PKCS1 公钥验签失败")
}
}
func TestBuildContent(t *testing.T) {
params := map[string]any{
"version": "1.0",
"appid": "abc",
"timestamp": "1504147887642",
"bizContent": "{\"a\":1}",
"nilField": nil, // null 不参与拼接
"empty": "", // 空字符串参与拼接
}
content, err := BuildContent(params)
if err != nil {
t.Fatalf("BuildContent 失败: %v", err)
}
want := "appid=abc&bizContent={\"a\":1}&empty=&timestamp=1504147887642&version=1.0"
if content != want {
t.Fatalf("拼接结果不符:\n got: %s\nwant: %s", content, want)
}
}
func TestSortJSONKeys(t *testing.T) {
// 乱序 + null 字段键按字典序重排null 剔除
in := []byte(`{"mpQuery":null,"authUrl":"https://a.com/x","expireTime":"2026-09-01 12:00:00"}`)
got := string(SortJSONKeys(in))
want := `{"authUrl":"https://a.com/x","expireTime":"2026-09-01 12:00:00"}`
if got != want {
t.Fatalf("排序结果不符:\n got: %s\nwant: %s", got, want)
}
// 嵌套对象递归排序
in2 := []byte(`{"b":{"d":1,"c":2},"a":3}`)
got2 := string(SortJSONKeys(in2))
want2 := `{"a":3,"b":{"c":2,"d":1}}`
if got2 != want2 {
t.Fatalf("嵌套排序结果不符:\n got: %s\nwant: %s", got2, want2)
}
// 数组元素递归排序
in3 := []byte(`[{"z":1,"a":2},{"q":3}]`)
got3 := string(SortJSONKeys(in3))
want3 := `[{"a":2,"z":1},{"q":3}]`
if got3 != want3 {
t.Fatalf("数组排序结果不符:\n got: %s\nwant: %s", got3, want3)
}
}