golang 支付宝SHA1withRSA加密

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

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

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