package controllers import ( "crypto/sha1" "encoding/hex" "sort" "strings" "testing" "server/services/wechatmini" "server/services/wechatmp" ) // sign 复刻微信签名算法:sha1(sort(token, timestamp, nonce)) func sign(token, timestamp, nonce string) string { arr := []string{token, timestamp, nonce} sort.Strings(arr) sum := sha1.Sum([]byte(strings.Join(arr, ""))) return hex.EncodeToString(sum[:]) } // signMsg 复刻加密消息签名:sha1(sort(token, timestamp, nonce, encrypt)) func signMsg(token, timestamp, nonce, encrypt string) string { arr := []string{token, timestamp, nonce, encrypt} sort.Strings(arr) sum := sha1.Sum([]byte(strings.Join(arr, ""))) return hex.EncodeToString(sum[:]) } // 明文 / 兼容模式:签名正确时原样回显 echostr func TestVerifyPushEchostrPlain(t *testing.T) { cfgs := []wechatmini.PushConfig{ {AppID: "wxApp", Token: "tokenPlain", EncryptMode: wechatmp.EncryptModePlain, DataFormat: wechatmini.DataFormatXML}, } ts, nonce, echostr := "1700000000", "abc123", "hello-wechat" got, ok := verifyPushEchostr(cfgs, ts, nonce, sign("tokenPlain", ts, nonce), "", echostr) if !ok { t.Fatal("明文模式签名正确,应验证通过") } if got != echostr { t.Fatalf("应原样回显 echostr,实际 %q", got) } if _, ok := verifyPushEchostr(cfgs, ts, nonce, "bad-signature", "", echostr); ok { t.Fatal("错误签名不应通过") } if _, ok := verifyPushEchostr(cfgs, ts, nonce, sign("tokenPlain", ts, nonce), "", ""); ok { t.Fatal("缺少 echostr 不应通过") } } // 安全模式:echostr 为密文,验签 + 解密后回显明文 func TestVerifyPushEchostrSafeMode(t *testing.T) { key := wechatmini.GeneratePushAESKey() cfgs := []wechatmini.PushConfig{ {AppID: "wxApp", Token: "tokenSafe", AESKey: key, EncryptMode: wechatmp.EncryptModeSafe, DataFormat: wechatmini.DataFormatXML}, } ts, nonce := "1700000000", "abc123" plain := "encrypted-echo-str" encrypt, err := wechatmp.EncryptMessage(key, "wxApp", plain) if err != nil { t.Fatalf("加密失败: %v", err) } got, ok := verifyPushEchostr(cfgs, ts, nonce, "", signMsg("tokenSafe", ts, nonce, encrypt), encrypt) if !ok { t.Fatal("安全模式签名正确,应验证通过") } if got != plain { t.Fatalf("应回显解密后的明文,实际 %q", got) } if _, ok := verifyPushEchostr(cfgs, ts, nonce, "", "bad-msg-signature", encrypt); ok { t.Fatal("错误 msg_signature 不应通过") } }