分享
  1. 首页
  2. 文章

golang 支付宝SHA1withRSA加密

u012210379 · · 8326 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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 := "111110^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=%v\n", 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 : %v\n", 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, crypto.SHA1, digest)
 if err != nil {
 fmt.Errorf("rsaSign SignPKCS1v15 error")
 return "", err
 }
 data := base64.StdEncoding.EncodeToString(s)
 return string(data), nil
}

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


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:u012210379

查看原文:golang 支付宝SHA1withRSA加密

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
8326 次点击 ∙ 1 赞
1 回复 | 直到 2017年12月14日 14:17:41
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏