优化结构

This commit is contained in:
Yvan
2026-08-27 22:33:43 +08:00
parent 5052835fcb
commit e407d3ac10
86 changed files with 3151 additions and 726 deletions
+42 -16
View File
@@ -1,12 +1,17 @@
package payment
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/big"
"strings"
"time"
)
@@ -20,12 +25,16 @@ const (
var (
appleJWSLeafExtensionOID = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 6, 11, 1}
appleJWSIntermediateExtensionOID = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 6, 2, 1}
appleTrustedRootFingerprints = map[string]struct{}{
"63343abfb89a6a03ebb57e9b3f5fa7be7c4f5c756f3017b3a8c488c3653e9179": {},
}
)
// validateAppleJWSChain binds the leaf certificate used by GoPay for JWS
// signature verification to the intermediate and root certificates that
// GoPay validates against its embedded Apple trust anchor.
func validateAppleJWSChain(signedPayload string) error {
return validateAppleJWSChainWithRoots(signedPayload, appleTrustedRootFingerprints)
}
func validateAppleJWSChainWithRoots(signedPayload string, trustedRoots map[string]struct{}) error {
headerSegment, payloadSegment, signatureSegment, err := splitAppleJWS(signedPayload)
if err != nil {
return err
@@ -73,6 +82,10 @@ func validateAppleJWSChain(signedPayload string) error {
}
certificates = append(certificates, certificate)
}
rootFingerprint := sha256.Sum256(certificates[2].Raw)
if _, trusted := trustedRoots[hex.EncodeToString(rootFingerprint[:])]; !trusted {
return errors.New("Apple JWS 根证书不受信任")
}
if err = certificates[0].CheckSignatureFrom(certificates[1]); err != nil {
return fmt.Errorf("Apple JWS 叶子证书不属于声明的证书链: %w", err)
}
@@ -101,19 +114,20 @@ func validateAppleJWSChain(signedPayload string) error {
return errors.New("Apple JWS 中间证书缺少 Apple 签名扩展")
}
if hasVerificationTime {
roots := x509.NewCertPool()
roots.AddCert(certificates[2])
intermediates := x509.NewCertPool()
intermediates.AddCert(certificates[1])
if _, err = certificates[0].Verify(x509.VerifyOptions{
Roots: roots,
Intermediates: intermediates,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
CurrentTime: verificationTime,
}); err != nil {
return fmt.Errorf("验证 Apple JWS 证书链: %w", err)
}
if !hasVerificationTime {
verificationTime = time.Now()
}
roots := x509.NewCertPool()
roots.AddCert(certificates[2])
intermediates := x509.NewCertPool()
intermediates.AddCert(certificates[1])
if _, err = certificates[0].Verify(x509.VerifyOptions{
Roots: roots,
Intermediates: intermediates,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
CurrentTime: verificationTime,
}); err != nil {
return fmt.Errorf("验证 Apple JWS 证书链: %w", err)
}
if certificates[0].IsCA {
return errors.New("Apple JWS 叶子证书不能是 CA")
@@ -121,6 +135,18 @@ func validateAppleJWSChain(signedPayload string) error {
if certificates[0].KeyUsage != 0 && certificates[0].KeyUsage&x509.KeyUsageDigitalSignature == 0 {
return errors.New("Apple JWS 叶子证书不允许数字签名")
}
publicKey, ok := certificates[0].PublicKey.(*ecdsa.PublicKey)
if !ok || publicKey.Curve != elliptic.P256() {
return errors.New("Apple JWS 叶子证书不是 P-256 ECDSA 公钥")
}
signature, err := base64.RawURLEncoding.DecodeString(signatureSegment)
if err != nil || len(signature) != 64 {
return errors.New("Apple JWS ES256 签名格式无效")
}
digest := sha256.Sum256([]byte(headerSegment + "." + payloadSegment))
if !ecdsa.Verify(publicKey, digest[:], new(big.Int).SetBytes(signature[:32]), new(big.Int).SetBytes(signature[32:])) {
return errors.New("Apple JWS 签名校验失败")
}
return nil
}