nodejs 支付宝签名求助
发布于 7 年前 作者 zoobop 6670 次浏览 来自 问答

支付宝签名的时候是对请求的所有参数进行加密吗,包括sing和sing_type吗,然后再对sing的值进行替换?还有RSA加密是用crypto?这个库能用RSA2吗? 哪位大佬能给个demo例子,微信已经搞定了就差支付宝了,十分感谢啊。

17 回复

1.筛选并排序

获取所有请求参数,不包括字节类型参数,如文件、字节流,剔除sign字段,剔除值为空的参数,并按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。

2.拼接

将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,此时生成的字符串为待签名字符串。

文档看到了

const request = require(‘request-promise’); const crypto = require(‘crypto’);

const private_key = "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVUrhz0RSgB8LS4//DOO9K7uAUEXF+fJdTX8V9FZI90TKun/kb\nRV/ku2em6V3ODjUcin33ayk9sJlEHST6p1FGQGa6+AaxX/qzQYbMpCCIlSx4S3Uv\nf7C0QovqHOw34YJxXY2He8T7TRXdSRZQGAnzrvhajJFpjsU6qNj2+kcATQIDAQAB\nAoGAVCbOprl69mo5W7Ifieai1x+Ge8Qpzmjd1UD5ig+BYittX9+xiCWE35liGUEE\nBS4rm3eym3DFkxVgULNijBKHB4NxTpWlSZZNGoee3+w9mc3pDbuw9BBDIJZTu3yg\n2zcXeNYQDvLh8KJZO/pX0VVpYLXBSzR4HsmuKGo+QPbSg+ECQQD/keIIqY77JxP5\nNmdKUG2NJcT1Jouc6hkj72mIapbUEy+q6DUjPRYA4KatGDlsYvyKEs08ZFE3aa7W\nsS/S6os1AkEA1a6igOCDfQfRa3PmS5up1b6YwJ6h0GzdRXHBrt9TH4dmFTj9/XZD\nx/JAd1Y7DwDTfDa12FFD2mxACS9SQhyruQJBAJxCD9eIBFne7MFk2AaB4ll4jFHv\nfVE1eKWWDgpQUWPdTznJvCONh9SFhqMyunlglFO/ZyjTlSyyOyodL8ZfjTkCQQC/\nOVYx0Tm6dXmjGIg6l2aIYtXeYtfaZuIp2GCE91Qy/f+L9IHQBrsnvxKT+TZG+e1I\n1skreaYoXQF9dry9b1z5AkAemouMCsZUFwMFX77tL2R/UWqD+nF0kGLuuJGempow\n4Zm2TdHOUXW1EhqPRVjcCahCPeckHJ2NNJS1LCsnUOh7\n-----END RSA PRIVATE KEY-----";

const public_key = ’-----BEGIN PUBLIC KEY-----\n’ + ‘MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIgHnOn7LLILlKETd6BFRJ0Gqg\n’ + ‘S2Y3mn1wMQmyh9zEyWlz5p1zrahRahbXAfCfSqshSNfqOmAQzSHRVjCqjsAw1jyq\n’ + ‘rXaPdKBmr90DIpIxmIyKXv4GGAkPyJ/6FTFY99uhpiq0qadD/uSzQsefWo0aTvP/\n’ + ‘65zi3eof7TcZ32oWpwIDAQAB\n’ + ’-----END PUBLIC KEY-----’;

function getNowFormatDate() { var date = new Date(); var seperator1 = “-”; var seperator2 = “:”; var month = date.getMonth() + 1; var strDate = date.getDate(); var strHour = date.getHours(); var strMin = date.getMinutes(); var strSecond = date.getSeconds(); if (month >= 1 && month <= 9) { month = “0” + month; } if (strDate >= 0 && strDate <= 9) { strDate = “0” + strDate; } if (strHour >= 0 && strHour <= 9) { strHour = “0” + strHour; } if (strMin >= 0 && strMin <= 9) { strMin = “0” + strMin; } if (strSecond >= 0 && strSecond <= 9) { strSecond = “0” + strSecond; }

var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
    + " " + strHour + seperator2 + strMin
    + seperator2 + strSecond;
return currentdate;

}

function createRSASign(params, privateKey) { let signer = crypto.createSign(‘RSA-SHA1’); let prestr = linkSignStrUtil(params); let sign = signer.update(new Buffer(prestr, ‘utf-8’)).sign(privateKey, ‘base64’); return sign; }

function verifyRSASign(params, sign, publicKey) { let verify = crypto.createVerify(‘RSA-SHA1’); let prestr = linkSignStrUtil(params); return verify.update(new Buffer(prestr, ‘utf-8’)).verify(publicKey, sign, ‘base64’); }

function linkSignStrUtil(params) { let keys = Object.keys(params); keys.sort(); let str = ‘’; for(let i of keys){ str += i + ‘=’ + params[i] + ‘&’; } str = str.slice(0,-1); return str; }

function linkSignStr(params) { let keys = Object.keys(params); keys.sort(); let str = ‘’; for(let i of keys){ str += i + ‘=’ + encodeURIComponent(params[i]) + ‘&’; } str = str.slice(0,-1); return str; }

/*

keyValues.put(“app_id”, app_id);

keyValues.put(“biz_content”, “{“timeout_express”:“30m”,“product_code”:“QUICK_MSECURITY_PAY”,“total_amount”:“0.01”,“subject”:“1”,“body”:“我是测试数据”,“out_trade_no”:”" + getOutTradeNo() + “”}");

keyValues.put(“charset”, “utf-8”);

keyValues.put(“method”, “alipay.trade.app.pay”);

keyValues.put(“sign_type”, “RSA”);

keyValues.put(“timestamp”, “2016-07-29 16:55:53”);

keyValues.put(“version”, “1.0”); */ function buildOrderParamMap(app_id,total_amount,subject,out_trade_no,notify_url,seller_id) { let biz_content = { ‘timeout_express’ : ‘30m’, ‘seller_id’ : seller_id + ‘’, ‘product_code’ : ‘QUICK_MSECURITY_PAY’, ‘total_amount’ : total_amount + ‘’, ‘subject’ : subject + ‘’, ‘out_trade_no’ : out_trade_no + ‘’, }; return { ‘app_id’ : app_id + ‘’, ‘charset’ : ‘utf-8’, ‘method’ : ‘alipay.trade.app.pay’, ‘sign_type’ : ‘RSA’, ‘timestamp’ : getNowFormatDate(), ‘version’ : ‘1.0’, ‘biz_content’ : JSON.stringify(biz_content), ‘notify_url’ : notify_url + ‘’, }; }

function buildOrderQueryMapByOutTradeNo(app_id,out_trade_no) { let biz_content = { ‘out_trade_no’: out_trade_no }; return { ‘app_id’ : app_id, ‘charset’ : ‘utf-8’, ‘method’ : ‘alipay.trade.query’, ‘sign_type’ : ‘RSA’, ‘timestamp’ : getNowFormatDate(), ‘version’ : ‘1.0’, ‘biz_content’ : JSON.stringify(biz_content) };

} //authInfo = app_id=2016082401792488&biz_content={“timeout_express”:“30m”,“product_code”:“QUICK_MSECURITY_PAY”,“total_amount”:“0.01”,“subject”:“1”,“body”:“我是测试数据”,“out_trade_no”:“120916552497326”}&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA&timestamp=2016-07-29 16:55:53&version=1.0

function buildOrderQueryMapByTradeNo(app_id,trade_no) { let biz_content = { ‘trade_no’: trade_no }; return { ‘app_id’ : app_id, ‘charset’ : ‘utf-8’, ‘method’ : ‘alipay.trade.query’, ‘sign_type’ : ‘RSA’, ‘timestamp’ : getNowFormatDate(), ‘version’ : ‘1.0’, ‘biz_content’ : JSON.stringify(biz_content) };

}

module.exports = { ‘linkSignStr’ : linkSignStr, ‘createRSASign’ : createRSASign, ‘verifyRSASign’ : verifyRSASign, ‘buildOrderParamMap’ : buildOrderParamMap, ‘buildOrderQueryMapByOutTradeNo’ : buildOrderQueryMapByOutTradeNo, ‘buildOrderQueryMapByTradeNo’ : buildOrderQueryMapByTradeNo };

@zoobop 我把我的支付宝demo放在下面了,可以参考一下

@zy445566 我验签老是失败,能不能指点一下。

/**
 * 支付宝验证
 * */
Pay.prototype.aliPayVerify = function (params) {
    const arr = [];
    for (const name in params) {
        if (name != 'sign' && name != 'sign_type')
            arr.push(name + '=' + params[name])
    }
    arr.sort();
    const prestr = arr.join('&');
    prestr = unescape(encodeURIComponent(prestr));
    const public_key = this.chunk_split(CODE.PayConf.AliPay.public_key, 64, '\n');
    return crypto.createVerify('RSA-SHA1').update(prestr).verify(public_key, params.sign, 'base64');
};

@zsea 你是用我这个包吗?

@zy445566 不是,以前没发现你这个包。

@zy445566 我是在接收支付宝返回给我的数据的时候验签失败。

@zsea 我6楼完整代码给你了啊,params 就是支付宝callback的参数

@zsea 哦,我这边没有做验签,只做了发送请求获取数据

个人能申请支付宝开发?

支付宝不是有官方的库么 Alipay

支付宝还是用官方库吧,支付宝的签名接口很混乱,自己搞很麻烦.

@coordcn @Ireoo 那不是官方库,官方库只有 image.png https://doc.open.alipay.com/docs/doc.htm?articleId=103419&docType=1 alipay应该是被@lodengo抢注了 有官方库谁去搞私库,支付宝官方的git地址是: https://github.com/alipay 管理者是:https://github.com/lifesinger

@zy445566 问题不大,只要能用,源码没问题就OK

@zy445566

我没说楼上的是官方库, 我印象中阿里提供nodejs版的啊,难道是我记错了?

没有也不要紧,自己照着文档实现一个,我自己用lua也实现了一版,只要注意阿里文档里的坑就行了.

回到顶部