sha256withrsa_verifier.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright 2021 Tencent Inc. All rights reserved.
  2. // Package verifiers 微信支付 API v3 Go SDK 数字签名验证器
  3. package verifiers
  4. import (
  5. "context"
  6. "crypto"
  7. "crypto/rsa"
  8. "crypto/sha256"
  9. "encoding/base64"
  10. "fmt"
  11. "strings"
  12. "github.com/wechatpay-apiv3/wechatpay-go/core"
  13. )
  14. // SHA256WithRSAVerifier SHA256WithRSA 数字签名验证器
  15. type SHA256WithRSAVerifier struct {
  16. // Certificates 微信支付平台证书Map,key: 平台证书序列号, value: 微信支付平台证书
  17. certGetter core.CertificateGetter
  18. }
  19. // Verify 对数字签名信息进行验证
  20. func (verifier *SHA256WithRSAVerifier) Verify(ctx context.Context, serialNumber, message, signature string) error {
  21. err := checkParameter(ctx, serialNumber, message, signature)
  22. if err != nil {
  23. return err
  24. }
  25. if verifier.certGetter == nil {
  26. return fmt.Errorf("verifier has no validator")
  27. }
  28. sigBytes, err := base64.StdEncoding.DecodeString(signature)
  29. if err != nil {
  30. return fmt.Errorf("verify failed: signature not base64 encoded")
  31. }
  32. certificate, ok := verifier.certGetter.Get(ctx, serialNumber)
  33. if !ok {
  34. return fmt.Errorf("certificate[%s] not found in verifier", serialNumber)
  35. }
  36. hashed := sha256.Sum256([]byte(message))
  37. err = rsa.VerifyPKCS1v15(certificate.PublicKey.(*rsa.PublicKey), crypto.SHA256, hashed[:], sigBytes)
  38. if err != nil {
  39. return fmt.Errorf("verify signature with public key err:%s", err.Error())
  40. }
  41. return nil
  42. }
  43. // GetSerial 获取可验签的平台证书序列号
  44. func (verifier *SHA256WithRSAVerifier) GetSerial(ctx context.Context) (string, error) {
  45. return verifier.certGetter.GetNewestSerial(ctx), nil
  46. }
  47. func checkParameter(ctx context.Context, serialNumber, message, signature string) error {
  48. if ctx == nil {
  49. return fmt.Errorf("context is nil, verifier need input context.Context")
  50. }
  51. if strings.TrimSpace(serialNumber) == "" {
  52. return fmt.Errorf("serialNumber is empty, verifier need input serialNumber")
  53. }
  54. if strings.TrimSpace(message) == "" {
  55. return fmt.Errorf("message is empty, verifier need input message")
  56. }
  57. if strings.TrimSpace(signature) == "" {
  58. return fmt.Errorf("signature is empty, verifier need input signature")
  59. }
  60. return nil
  61. }
  62. // NewSHA256WithRSAVerifier 使用 core.CertificateGetter 初始化 SHA256WithRSAVerifier
  63. func NewSHA256WithRSAVerifier(getter core.CertificateGetter) *SHA256WithRSAVerifier {
  64. return &SHA256WithRSAVerifier{certGetter: getter}
  65. }