支付寶支付RSA簽名,PKCS8轉RSA pem格式

 

作一個項目往移動端延伸,有原商家支付寶支付信息,此前是PC端的系統,使用JAVA,因此RSA的密鑰信息給到的是PKCS8格式的。我用的是golang語言,調用的函數不能直接使用PKCS8格式,想使用RSA格式,網上找了一下轉換的資料。結果找到以下命令:git

openssl rsa -in pri-pkcs8.pem -out pri-rsa-r.pemgithub

我直接把PKCS8那段只有一行的密鑰拷進文件中去執行,結果報錯。後來頭尾加入-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----。發現也不行。後來看到有先後轉換的一些例子,應該是須要換行的,看了下,發現65個字符換一行。將原來只有一行的密鑰按65分一行試,頭尾-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----分別一行,再試那個命令,果真能夠了。golang

 

如下是一些支付寶簽名的代碼:json

 

 
 
 
 import (
    "bytes"
    "crypto"
    "crypto/rsa"
    "crypto/sha1"
    "crypto/x509"
    "encoding/base64"
    "encoding/hex"
    "encoding/pem"
    "errors"
    "fmt"
    "io"
    "net/http"
    "net/url"
    //"math/rand"
    //"net/http"
    "sort"
    //"strings"
    //"time"
 
    "github.com/alecthomas/log4go"
)
 
 
 
 
 
 
 
 type ChargeInfo struct {
    Service     string `json:"service"`        // 接口名稱
    Partner     string `json:"partner"`        // 合做者身份ID
    Charset     string `json:"_input_charset"` // 商戶網站使用的編碼格式,僅支持UTF-8
    SignType    string `json:"sign_type"`      // 簽名方式 DSA、RSA、MD5三個值可選,必須大寫。
    Sign        string `json:"sign"`           // 簽名
    NotifyUrl   string `json:"notify_url"`     // 服務器異步通知頁面路徑
    ReturnUrl   string `json:"return_url"`     // 頁面跳轉同步通知頁面路徑(客戶端)
    OrderNo     string `json:"out_trade_no"`   // 商戶網站惟一訂單號
    Subject     string `json:"subject"`        // 商品名稱
    TotalFee    string `json:"total_fee"`      // 交易金額
    SellerId    string `json:"seller_id"`      // 賣家支付寶用戶號
    PaymentType string `json:"payment_type"`   // 支付類型。僅支持:1(商品購買)
    ShowUrl     string `json:"show_url"`       // 商品展現網址 用戶付款中途退出返回商戶網站的地址
}
 
func (o *APIHandler) ChargeOrderAliPay(userId int64, orderNo string) (*ChargeInfo, error) {
 
    log4go.Debug("ChargeOrderAliPay()... userId:%d, orderNo:%s", userId, orderNo)
 
    bookOrder, err := o.GetOrderByOrderNoDb(orderNo)
    if err != nil {
        log4go.Error("ChargeOrderAliPay(): GetOrderByOrderNoDb error.")
        return nil, err
    }
 
    mapParaValue := make(map[string]string)
 
    mapParaValue["service"] = ALIPAY_SERVICE
    mapParaValue["partner"] = ALIPAY_PARTNER
    mapParaValue["_input_charset"] = ALIPAY_CHARSET
    mapParaValue["notify_url"] = ALIPAY_NOTIFY_URL
    mapParaValue["return_url"] = o.sc.AlipayReturnUrl
    mapParaValue["out_trade_no"] = orderNo
    mapParaValue["subject"] = bookOrder.LineName
    mapParaValue["total_fee"] = fmt.Sprintf("%f", bookOrder.TotalPrice)
    mapParaValue["seller_id"] = ALIPAY_PARTNER
    mapParaValue["payment_type"] = ALIPAY_PAYMENT_TYPE
    mapParaValue["show_url"] = o.sc.AlipayShowUrl
 
    signedStr, err := o.AlipaySignParam(mapParaValue)
    if err != nil {
        log4go.Error("ChargeOrderAliPay(): AlipaySignParam error.")
        return nil, err
    }
 
    charge := ChargeInfo{
        Service:     mapParaValue["service"],
        Partner:     mapParaValue["partner"],
        Charset:     mapParaValue["_input_charset"],
        SignType:    ALIPAY_SIGN_TYPE,
        Sign:        signedStr,
        NotifyUrl:   mapParaValue["notify_url"],
        ReturnUrl:   mapParaValue["return_url"],
        OrderNo:     orderNo,
        Subject:     bookOrder.LineName,
        TotalFee:    mapParaValue["total_fee"],
        SellerId:    mapParaValue["seller_id"],
        PaymentType: mapParaValue["payment_type"],
        ShowUrl:     mapParaValue["show_url"],
    }
    return &charge, nil
}
 
func (o *APIHandler) AlipaySignParam(mapParam map[string]string) (string, error) {
 
    log4go.Debug("AlipaySignParam()...len(mapParam):%d", len(mapParam))
 
    mapDest := make(map[string]interface{})
    for k, v := range mapParam {
        mapDest[k] = interface{}(v)
    }
 
    // 參數排序
    signStr := o.GenAlipaySignString(mapDest)
    log4go.Debug("AlipaySignParam()...signStr:%s", signStr)
 
    // rsa加密
    block, _ := pem.Decode([]byte(ALIPAY_PRIVATE_KEY))
    if block == nil {
        log4go.Error("AlipaySignParam private_key error")
        return "", errors.New("pem.Decode error")
    }
 
    privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        log4go.Error("x509.ParsePKCS1PrivateKey-------privateKey----- error : %v", err)
        return "", err
    } else {
        log4go.Debug("x509.ParsePKCS1PrivateKey-------privateKey-----:%s", privateKey)
    }
 
    result, err := AlipayRsaSign(signStr, privateKey)
    if err != nil {
        log4go.Error("AlipayRsaSign error")
        return "", err
    }
    log4go.Debug("AlipayRsaSign result:%s", result)
    return result, nil
}
 
func (o *APIHandler) GenAlipaySignString(mapBody map[string]interface{}) (sign string) {
 
    log4go.Debug("GenAlipaySignString()...")
    sorted_keys := make([]string, 0)
    for k, _ := range mapBody {
        sorted_keys = append(sorted_keys, k)
    }
    sort.Strings(sorted_keys)
    var signStrings string
 
    index := 0
    for _, k := range sorted_keys {
        log4go.Debug("GenAlipaySignString() k=%s, v=%v", k, mapBody[k])
        value := fmt.Sprintf("%v", mapBody[k])
        if value != "" {
            signStrings = signStrings + k + "=" + value
        }
        // 最後一項後面不要&
        if index < len(sorted_keys)-1 {
            signStrings = signStrings + "&"
        }
        index++
    }
 
    return signStrings
}
 
/**
 * RSA簽名
 * @param $data 待簽名數據
 * @param $private_key_path 商戶私鑰文件路徑
 * return 簽名結果
 */
func AlipayRsaSign(origData string, privateKey *rsa.PrivateKey) (string, error) {
 
    h := sha1.New()
    h.Write([]byte(origData))
    digest := h.Sum(nil)
 
    s, err := rsa.SignPKCS1v15(nil, privateKey, crypto.SHA1, digest)
    if err != nil {
        log4go.Error("RsaSign() err=%s", err)
        return "", err
    }
    data := base64.StdEncoding.EncodeToString(s)
    return string(data), nil
}
相關文章
相關標籤/搜索