package main import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/base64" "encoding/json" "encoding/pem" "errors" "hash" "io/ioutil" "net/http" "net/url" "strings" "time" ) // DoRequest 支付宝支付统一HTTP调用接口 func DoRequest(appId, bizCcontent, curl, methodType string, privateKey *rsa.PrivateKey) (*map[string]interface{}, error) { var data = url.Values{} data.Add("app_id", appId) data.Add("method", methodType) data.Add("format", "json") data.Add("charset", "UTF-8") data.Add("sign_type", "RSA2") data.Add("timestamp", time.Now().Format("2006-01-02 15:04:05")) data.Add("version", "1.0") data.Add("biz_content", bizCcontent) signContentBytes, _ := url.QueryUnescape(data.Encode()) signature, err := getSign([]byte(signContentBytes), privateKey) if err != nil { return nil, err } data.Add("sign", signature) url := curl + "?" + data.Encode() client := http.Client{Jar: nil} req, _ := http.NewRequest("POST", url, nil) res, err := client.Do(req) if err != nil { return nil, err } bArr, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } m := map[string]interface{}{} err = json.Unmarshal(bArr, &m) return &m, nil } // 生成加密token func getSign(data []byte, PrivateKey *rsa.PrivateKey) (signature string, err error) { var h hash.Hash var hType crypto.Hash h = sha256.New() hType = crypto.SHA256 h.Write(data) d := h.Sum(nil) bs, err := rsa.SignPKCS1v15(rand.Reader, PrivateKey, hType, d) if err != nil { return "", err } signature = base64.StdEncoding.EncodeToString(bs) return } // 加载秘钥 func parsePrivateKey(key string) (*rsa.PrivateKey, error) { block, _ := pem.Decode([]byte(key)) if block == nil { return nil, errors.New("私钥格式不正确,无法解析PEM块") } if strings.ToUpper(block.Type) != "RSA PRIVATE KEY" { return nil, errors.New("私钥类型不正确,期望为RSA PRIVATE KEY但得到的是" + block.Type) } // 注意:这里使用x509.ParsePKCS1PrivateKey来解析PKCS#1格式的私钥 rsaPrivateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { return nil, err } return rsaPrivateKey.(*rsa.PrivateKey), nil }