加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang 支付宝SHA1withRSA加密

发布时间:2020-12-16 19:15:28 所属栏目:大数据 来源:网络整理
导读:SHA1大家用的挺多,RSA不多但用的也有,但像支付宝这样要求 SHA1 + RSA的恐怕就没几个了,写起来实在痛苦。而且一搜一片,却没几个能跑起来的。 刚才有个人在QQ上加我,问之前在支付宝集成的帖子里的SHA1withRSA是咋解决的。说实话,不是专门研究加密的,鬼知

SHA1大家用的挺多,RSA不多但用的也有,但像支付宝这样要求 SHA1 + RSA的恐怕就没几个了,写起来实在痛苦。而且一搜一片,却没几个能跑起来的。

刚才有个人在QQ上加我,问之前在支付宝集成的帖子里的SHA1withRSA是咋解决的。说实话,不是专门研究加密的,鬼知道报的错是什么玩意,比如这个:

signature,err := rsa.SignPKCS1v15(rand.Reader,this.privateKey,crypto.SHA1,hashed) //ParsePKCS8PrivateKey err asn1: structure error: tags don't match (16 vs {class:0 tag:2 length:129 isCompound:false}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} AlgorithmIdentifier

反正我是真心看的莫名其妙,不过不妨碍我们解决它,由于调用的是系统加密,所以基本可以肯定是套路问题。以下是在beego中集成支付宝的代码,大家可以参考下:

package controllers

import (
    "github.com/astaxie/beego"
    "fmt"
    "net/url"
    "time"
    "sort"
    "encoding/pem"
    "crypto/x509"
    "mlshop/shopUtils/AliSignUtil"
    "net/http"
    "io/ioutil"
    "mlshop/shopUtils/RandomStrUtil"
    "strings"
)

/** ali第三方授权或用户信息授权后回调地址。授权链接中配置的redirect_uri的值必须与此值保持一致 */

type AliAnswerController struct {
    beego.Controller
}

func (c *AliAnswerController) Get() {

    c.EnableRender = false
    fmt.Println("AliAnswerController=============get")

    //接收manager登录支付宝付款授权页面后 支付宝传递过来的回调信息
    auth_code,state := c.GetString("auth_code","-1"),c.GetString("state")
    if state == zfbRandomState {

        //根据 auth_code 获取 token
        getAliTokenByAuthCode(auth_code)

        fmt.Println("============== 开始批量付款 =============")

        service := "batch_trans_notify"
        partner := "20880000000000"
        _input_charset := "UTF-8"
        sign_type := "RSA"

        notify_url := "http://www.xxxx.com/xxx"
        account_name := "130000000"//todo 付款方的支付宝账户名
        detail_data := "222220^xxxx^name^0.01^beizhu0"//todo 付款的详细数据 格式为:流水号1^收款方账号1^收款账号姓名1^付款金额1^备注说明1|流水号2^收款方账号2^收款账号姓名2^付款金额2^备注说明2。
        batch_no := RandomStrUtil.GetRandomString(32)
        batch_num := "1"//付款总笔数
        batch_fee := "0.01"//付款总金额
        email := "xxxx@sina.com"//付款方的支付宝账号,支持邮箱和手机号2种格式
        pay_date := time.Now().Format(TIMELAYOUT3)//YYYYMMDD

        m := make(map[string]interface{})
        m["service"] = service
        m["partner"] = partner
        m["_input_charset"] = _input_charset
        m["sign_type"] = sign_type
        m["notify_url"] = notify_url
        m["account_name"] = account_name
        m["detail_data"] = detail_data
        m["batch_no"] = batch_no
        m["batch_num"] = batch_num
        m["batch_fee"] = batch_fee
        m["email"] = email
        m["pay_date"] = pay_date

        sign := aliPaySign(m)//签名

        requestLine := strings.Join([]string{"https://mapi.alipay.com/gateway.do","?service=" + service,"&partner=" + partner,"&_input_charset=" + _input_charset,"&notify_url=" + url.QueryEscape(notify_url),"&sign_type=" + sign_type,"&sign=" + sign,"&email=" + email,"&pay_date=" + pay_date,"&batch_no=" + batch_no,"&batch_num=" + batch_num,"&account_name=" + url.QueryEscape(account_name),"&batch_fee=" + batch_fee,"&detail_data=",url.QueryEscape(detail_data)},"")

        c.Redirect(requestLine, 302)
        //data := make(url.Values)
        //data["service"] = []string{service}
        //data["partner"] = []string{partner}
        //data["_input_charset"] = []string{_input_charset}
        //data["sign_type"] = []string{sign_type}
        //data["notify_url"] = []string{notify_url}
        //data["account_name"] = []string{account_name}
        //data["detail_data"] = []string{detail_data}
        //data["batch_no"] = []string{batch_no}
        //data["batch_num"] = []string{batch_num}
        //data["batch_fee"] = []string{batch_fee}
        //data["email"] = []string{email}
        //data["pay_date"] = []string{pay_date}
        //data["sign"] = []string{sign}
        //
        //
        ////把批量付款发送给目标服务器
        //_,err := http.PostForm("https://openapi.alipay.com/gateway.do",data)
        //if err != nil {
        // fmt.Println("批量付款出现错误",err.Error())
        // return
        //}else {
        // fmt.Println("批量付款完毕")
        //}

        fmt.Println("============== 结束批量付款 =============")

    } else {
        fmt.Println("接收到的支付宝回调发现state不一致 ",state," ",zfbRandomState)
    }

}

func getAliTokenByAuthCode(auth_code string) {

    fmt.Println("接收到的auth_code = ",auth_code)

    app_id := beego.AppConfig.String("ali_appId")
    method := "alipay.system.oauth.token"
    charset := "GBK"
    timestamp := time.Now().Format(TIMELAYOUT)
    version := "1.0"
    grant_type := "authorization_code"
    sign_type := "RSA"
    code := auth_code

    m := make(map[string]interface{})
    m["app_id"] = app_id
    m["method"] = method
    m["charset"] = charset
    m["timestamp"] = timestamp
    m["version"] = version
    m["grant_type"] = grant_type
    m["code"] = code
    m["sign_type"] = sign_type

    //换取 token
    data := make(url.Values)
    data["app_id"] = []string{app_id}
    data["method"] = []string{method}
    data["charset"] = []string{charset}
    data["sign_type"] = []string{sign_type}
    data["timestamp"] = []string{timestamp}
    data["sign"] = []string{aliPaySign(m)}//使用RSA进行签名
    data["version"] = []string{version}
    data["grant_type"] = []string{grant_type}
    data["code"] = []string{code}

    //把post表单发送给目标服务器 获取token
    res,err := http.PostForm("https://openapi.alipay.com/gateway.do",data)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer res.Body.Close()

    bodyBytes,err := ioutil.ReadAll(res.Body)//其中含有 token
    fmt.Println("把post表单发送给目标服务器 获取token 返回的数据---",string(bodyBytes),err)

}

func aliPaySign(mReq map[string]interface{}) string {

    //STEP 1,对key进行升序排序.
    sorted_keys := make([]string, 0)
    for k,_ := range mReq {
        sorted_keys = append(sorted_keys,k)
    }
    sort.Strings(sorted_keys)

    //STEP2,对key=value的键值对用&连接起来,略过空值
    var signStrings string
    for i,k := range sorted_keys {
        //fmt.Printf("k=%v,v=%vn",k,mReq[k])
        value := fmt.Sprintf("%v",mReq[k])
        if value != "" {
            if i != (len(sorted_keys) - 1) {
                signStrings = signStrings + k + "=" + value + "&"
            } else {
                signStrings = signStrings + k + "=" + value//最后一个不加此符号
            }
        }
    }
    fmt.Println("生成的待签名---->",signStrings)

    //============================= 开始签名 ==================================
    block,_ := pem.Decode([]byte(`-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQCsAocILoBYZqhMYDg40AFZTUiFjcSxwrUXOF0rgw8hh98tP+Ox 4awokuF+FJn8qN/9k9gFz9j7zM694vNv976W60k2ye6uiQdQy/gOJh+ciFME3kAH QoyvuItKRec+3cEhwblpuY7Gchk0mk22WXWyAHuNGXcCMGSJo9ugGnPDUwIDAQAB AoGARDgcZdpLfMP6K5Bdu+qDHm/QO2emgvm96J+qE/++mIXStZeJLptaNB1M4Tw6 dkJj06Y3Htb4L6ViuVyxP875/yqKocNur4KeoTLC/t+9L7f6jey7GCvWlCcpp97A NiVCPILG+7Py2+xGyv0tQT+98yJqTb0yA0nIsmq1XpmjkQECQQDUmVH8L6mJvyzj xDA32jLKoQLWyJTvzkBxeTnsuTL6GqXEcj9HN0Q1qEyTl/DcN5YfACL4XevV1NNV s6CrKEojAkEAzx/5d3aAI3dg9VHfAcWdiUZ5uTbx+qpDfZ4CtoyhEfolRGTiy2SC y9GDrtpY3NO1mm+D5lIM3HPbTgAxtvm9EQJADmI5K8jFva4TiW1ynbTDjvYJzSJR AVCBB6xeAOgezNEUug/IvDa/BKpYU/wJrbyNCZfmxnqE87ise7Xlfu8A5QJBAJTP Bx9SLvvMMAfwm0UdonJXBOsR08Zg/35HwPFAlhRhYNcDmIHCo8olq/M7Am8dV7Mt /VjDiGP2hRBESXOJd9ECPxeHMhK4prFTN1N/+fHcnbB61P89mIsH5ff38D9uEwa/ sLqen0K1ibjhgbcs0LjoVklK9fxJ5AK7SwU0Oxaq0w== -----END RSA PRIVATE KEY----- `))
    if block == nil {
        fmt.Println("rsaSign private_key error")
        return ""
    }

    privateKey,err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        fmt.Printf("x509.ParsePKCS1PrivateKey-------privateKey----- error : %vn",err)
        return ""
    } else {
        //fmt.Println("x509.ParsePKCS1PrivateKey-------privateKey-----",privateKey)
    }

    result,err := alipay.RsaSign(signStrings,privateKey)
    fmt.Println("alipay.RsaSign=========",result,err)
    return result
}


func (c *AliAnswerController) Post() {
    c.Ctx.WriteString("success")
}
/** * RSA签名 * @param $data 待签名数据 * @param $private_key_path 商户私钥文件路径 * return 签名结果 */
func RsaSign(origData string,privateKey *rsa.PrivateKey) (string,error) {

    h := sha1.New()
    h.Write([]byte(origData))
    digest := h.Sum(nil)

    s,err := rsa.SignPKCS1v15(nil,privateKey,digest)
    if err != nil {
        fmt.Errorf("rsaSign SignPKCS1v15 error")
        return "",err
    }
    data := base64.StdEncoding.EncodeToString(s)
    return string(data),nil
}

如果,当然希望没有这个如果,按照上面的法子依然存在问题,大家可以去github搜下go alipay,再试试看吧。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读