49 lines
1.8 KiB
Go
49 lines
1.8 KiB
Go
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
|
||
}
|