package utils import ( "crypto/hmac" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" mathRand "math/rand" "os" "strings" "time" ) const ( RSAAlgorithm = "RSA" SignatureAlgorithm = "SHA1WithRSA" letters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ) // EncryptWithRSA 使用 RSA 公钥加密数据 func EncryptWithRSA(publicKey *rsa.PublicKey, data []byte) ([]byte, error) { encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, data) if err != nil { return nil, err } return encrypted, nil } // DecryptWithRSA 使用 RSA 私钥解密数据 func DecryptWithRSA(privateKey *rsa.PrivateKey, encrypted []byte) ([]byte, error) { hash, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encrypted, nil) if err != nil { return nil, err } return hash, nil } // 解析RSA公钥 func ParsePublicKeyFromPEM() (publicKey *rsa.PublicKey, err error) { pemBlock, err := os.ReadFile("./conf/rsa_public_key.pem") block, _ := pem.Decode(pemBlock) if block == nil { FileLog.Error("公钥解析失败") return nil, errors.New("公钥解析失败") } key, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } publicKey = key.(*rsa.PublicKey) return } // 解析RSA私钥 func ParsePrivateKeyFromPEM() (privateKey *rsa.PrivateKey, err error) { pemBlock, err := os.ReadFile("./conf/rsa_private_key.pem") block, _ := pem.Decode(pemBlock) if block == nil { FileLog.Error("私钥解析失败") return nil, errors.New("公钥解析失败") } key, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } privateKey = key.(*rsa.PrivateKey) return } type SignatureParam struct { Nonce string `json:"nonce"` TimeStamp string `json:"timestamp"` AppId string `json:"appId"` } func (sp *SignatureParam) ToString() string { return fmt.Sprintf("appid=%s&nonce=%s×tamp=%s", sp.AppId, sp.Nonce, sp.TimeStamp) } type HeaderParam struct { Signature string `json:"signature"` Nonce string `json:"nonce"` TimeStamp string `json:"timestamp"` AppId string `json:"appId"` } func GenerateSignatureAndHeaders() (headerParam HeaderParam, err error) { if APP_ID == "" { FileLog.Error("APP_ID为空") err = errors.New("生成签名头失败,APP_ID未配置") return } if SECRET == "" { FileLog.Error("SECRET为空") err = errors.New("生成签名头失败,SECRET未配置") return } signParam := SignatureParam{ AppId: APP_ID, Nonce: randomString(32), TimeStamp: fmt.Sprintf("%d", time.Now().Unix()), } signature, err := generateHMACSHA256(SECRET, signParam.ToString()) if err != nil { FileLog.Error("生成签名失败", err) return } headerParam.Nonce = signParam.Nonce headerParam.TimeStamp = signParam.TimeStamp headerParam.AppId = signParam.AppId headerParam.Signature = signature return } func generateHMACSHA256(secret, data string) (encoded string, err error) { h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(data)) signature := h.Sum(nil) // Base64 编码 encoded = base64.StdEncoding.EncodeToString(signature) // 替换 + 和 / 为 - 和 _ encoded = strings.ReplaceAll(encoded, "+", "-") encoded = strings.ReplaceAll(encoded, "/", "_") return } func randomString(size int) string { ret := make([]byte, size) for i := range ret { ret[i] = letters[mathRand.Intn(len(letters))] } return string(ret) }