Files
soul-yongping/soul-api/internal/wechat/transferv3/sign.go

49 lines
1.8 KiB
Go
Raw Normal View History

package transferv3
import (
"crypto"
"crypto/rsa"
"crypto/sha256"
"encoding/base64"
"fmt"
"strings"
)
// BuildSignMessage 构建请求签名串(文档:请求方法\n请求URL路径\n时间戳\n随机串\n请求报文主体\n
func BuildSignMessage(method, urlPath, timestamp, nonce, body string) string {
return method + "\n" + urlPath + "\n" + timestamp + "\n" + nonce + "\n" + body + "\n"
}
// Sign 使用商户私钥 SHA256withRSA 签名,返回 Base64
func Sign(signMessage string, privateKey *rsa.PrivateKey) (string, error) {
h := sha256.Sum256([]byte(signMessage))
sig, err := rsa.SignPKCS1v15(nil, privateKey, crypto.SHA256, h[:])
if err != nil {
return "", fmt.Errorf("rsa sign: %w", err)
}
return base64.StdEncoding.EncodeToString(sig), nil
}
// BuildAuthorization 构建 Authorization 头(文档格式)
func BuildAuthorization(mchID, nonce, signature, timestamp, serialNo string) string {
return fmt.Sprintf(`WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",signature="%s",timestamp="%s",serial_no="%s"`,
mchID, nonce, signature, timestamp, serialNo)
}
// BuildVerifyMessage 构建回调验签串(文档:时间戳\n随机串\n请求报文主体\n
func BuildVerifyMessage(timestamp, nonce, body string) string {
return timestamp + "\n" + nonce + "\n" + body + "\n"
}
// VerifySignature 使用平台公钥验证回调签名Wechatpay-Signature 为 Base64
func VerifySignature(timestamp, nonce, body, signatureBase64 string, publicKey *rsa.PublicKey) bool {
msg := BuildVerifyMessage(timestamp, nonce, body)
sig, err := base64.StdEncoding.DecodeString(strings.TrimSpace(signatureBase64))
if err != nil {
return false
}
h := sha256.Sum256([]byte(msg))
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, h[:], sig)
return err == nil
}