阅读数:

nodejs生成签名

0

说明

为了api数据访问的安全性,我们常用的几种做法:
1、参数加密;
2、时间戳校验;
3、token校验;
4、签名校验;
相比较而言,签名校验是最安全的方式,比如qq,微信,支付宝的相关数据接口都是采用签名的方式。
我们在实际项目中和网易进行对接的过程中也遇到了签名的问题,下面简单分享下nodejs环境下,签名和
校验的方法

实现

这里我们使用nodejs自带的Crypto加解密算法库;它主要提供了加密、解密、签名、验证等功能。这里我们重点介绍签名和验证方法。加密离不开hash算法,Crypto支持的hash算法有如下好多种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[ 'DSA',
'DSA-SHA',
'DSA-SHA1',
'DSA-SHA1-old',
'RSA-MD4',
'RSA-MD5',
'RSA-MDC2',
'RSA-RIPEMD160',
'RSA-SHA',
'RSA-SHA1',
'RSA-SHA1-2',
'RSA-SHA224',
'RSA-SHA256',
'RSA-SHA384',
'RSA-SHA512',
'dsaEncryption',
'dsaWithSHA',
'dsaWithSHA1',
'dss1',
'ecdsa-with-SHA1',
'md4',
'md4WithRSAEncryption',
'md5',
'md5WithRSAEncryption',
'mdc2',
'mdc2WithRSA',
'ripemd',
'ripemd160',
'ripemd160WithRSA',
'rmd160',
'sha',
'sha1',
'sha1WithRSAEncryption',
'sha224',
'sha224WithRSAEncryption',
'sha256',
'sha256WithRSAEncryption',
'sha384',
'sha384WithRSAEncryption',
'sha512',
'sha512WithRSAEncryption',
'shaWithRSAEncryption',
'ssl2-md5',
'ssl3-md5',
'ssl3-sha1',
'whirlpool' ]

这里我们以和网易对接为例,使用RSA-SHA1算法
首先引用crypto算法库;

1
const crypto = require('crypto');

mac环境下,我们先利用openssl工具生成 private.pem和public.pem 私钥和公钥,用来生成和验证签名
1、安装openssl mac一般自带
2、打开命令行工具(生成1024位的私钥)

1
openssl genrsa -out rsa_private_key.pem 1024

3、把RSA私钥转换成PKCS8格式(当然可以不用转,看格式需要)

1
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt

4、生成公钥

1
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

5、生成最终文件
pem

签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 获取rsa签名
*/
function getRSASign(words) {
fs.readFile('file/rsa_private_key.pem', 'utf-8', function (err, prikey) {
if (err) {
return 'error';
} else {
var algorithm = 'RSA-SHA1';
var privatePem = prikey;
var key = privatePem.toString();
var sig = signer(algorithm, key, words); //数字签名
return sig;
}
});
}
function signer(algorithm, key, data) {
var sign = crypto.createSign(algorithm);
sign.update(data);
var sig = sign.sign(key, 'hex');
return sig;
}

验证

1
2
3
4
5
6
7
8
function verify(sig,data){
var algorithm = 'RSA-SHA1';
var publicPem = fs.readFileSync('file/rsa_public_key.pem');
var pubkey = publicPem.toString();
var verify = crypto.createVerify(algorithm);
verify.update(data);
return verify.verify(pubkey, sig, 'hex')
}

测试

1
2
3
4
var data = "abcdef"; //传输的数据
var sign = getRSASign(data);
console.log(verify,data); // true
console.log(verify,data + 'HI'); // flase

0
赏点咖啡钱^.^