Node.js的加密模块crypto之使用Sign类生成数字签名并使用Verify类验证数字签名

 2015年07月21日    4475     声明


在网络中传输的数据,除可使用Cipher类进行数据加密外,还可以对数据生成数字签名,以防止在传输过程中对数据进行修改。在Node.js的crypto模块中,封装了用于生成数字签名的类Sign及用于验证数字签名的类Verify

  1. Sign类的创建
  2. Sign类简介
  3. Verify类的创建
  4. Verify类简介
  5. 签名类Sign及签名验证类Verify使用示例


1. 创建Sign类:crypto.createSign(algorithm)

createSign()方法会根据传入的算法创建并返回一个Sign数据签名对象。algorithm为OpenSSL中支持的算法,比如:'RSA-SHA256'


2. Sign类简介

Sign签名对象是一个可读写的Stream流。可以使用Sign类中的update方法写入需要签名的数据,数据输入完成后通过sign方法返回数据的数字签名。

  • sign.update(data):更新Sign类的签名数据,data为要更新的数据,由于Sign是一个可读写的流,此方法可以被多次调用。
  • sign.sign(private_key, [output_format]):根据传送给Sign的数据来计算数字签名,private_key可以是一个对象或是字符串。如果为字符串时,则是一个包含了签名私钥的字符串,该私钥用的是PEM编码的。如是为对象时,对象如下:
    • key:包含 PEM 编码的私钥
    • passphrase:私钥的密码
    output_format:返回值的编码格式, 格式可以是 'binary''hex''base64'。如果没有设置 ,将返回Buffer
    注:调用sign()后不能再使用sign对象。


3. 创建Verify类:crypto.createVerify(algorithm)

createVerify()方法会根据传入的算法创建并返回一个Verify签名验证对象。algorithm为OpenSSL中支持的算法,比如:'RSA-SHA256'createVerify()方法为createSign()方法的镜像方法。


4. Verify类简介

Verify验证对象也是一个可读写的Stream流。被写入的数据将会被用来验证提供的数字签名,在所有的数据被写入后,如果提供的数字签名有效,verify函数会返回真。

  • verify.update(data):更新验证对象的数据,参数data为验证对象的更新数据。因为其本身是一个流,所以可以被多次调用。
  • verifier.verify(object, signature, [signature_format]):验证被签名的数据是否正确。参数 object是包含了PEM编码对象的字符串,它可以是:RSA公钥、DSA公钥、X.509证书。
    signature是之前计算出来的数字签名,signature_format 可以是 'binary''hex''base64',如果没有指定编码方式则默认是Buffer对象。
    注意:verifier 对象不能在 verify()方法之后调用。


5. 签名类Sign及签名验证类Verify使用示例

当前文件夹下有文件file1,文件内容为:abcdef。读取文件内容,使用Sign类对文件内容进行签名,再用Cipher类对文件内容及签名进行验证:

var crypto = require('crypto');
var fs = require('fs');

var sign = crypto.createSign('RSA-SHA256');
var verify = crypto.createVerify('RSA-SHA256');

var privateKey = fs.readFileSync('./rsa/ca.key').toString(); 		//rsa私钥
var publicKey = fs.readFileSync('./rsa/ca.crt').toString();		//rsa公钥

var s = fs.ReadStream('./file1');
s.on('data', function(d) {
  sign.update(d);
  verify.update(d);
});

s.on('end', function() {
    var signture = sign.sign(privateKey);				//生成签名

    var result = verify.verify(publicKey, signture);	//验证签名
    console.log(result);						//true
});

上面代码中使用的ca.key和ca.crt是使用OpenSSL生成的Rsa私钥和公钥。

一个简单的Rsa生成步骤:

1. 生成Rsa私钥

openssl genrsa -out ca.key

2. 使用私钥创建根证书,即:公钥

openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/C=CN/ST=BEIJING/L=BEIJING/O=Your Company Name/OU=Your Root CA"