Node.js crypto模块

本文深入探讨了Node.js中的加密技术,包括哈希算法如MD5及SHA系列,HMAC加密,以及各种对称和非对称加密算法的应用。特别介绍了如何在Node.js中使用这些加密方法,并提供了详细的代码示例。

The crypto module provides cryptographic functionality that includes a set of wrappers for OpenSSL’s hash, HMAC, cipher, decipher, sign and verify functions.

Use require(‘crypto’) to access this module.

加密模块提供的加密功能包括一套OpenSSL的哈希算法的包装,HMAC加密,解密,签名和验证函数。

在nodejs的命令行模式下默认引入了readline模块,但是如果要执行node.js脚本文件的话还是需要显示引入readline模块。

const crypto = require('crypto');

Hash加密

hash支持的算法如下:

const crypto = require('crypto');
crypto.getHashes();
/*
返回
[ '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' ]
*/

以”md5加密”为例:

Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,它将一个任意长度的字节串变换成一个32位的十六进制数字串,用以提供消息的完整性保护。

MD5算法具有以下特点:

  1. 压缩性:任意长度的数据,算出的MD5值长度都是固定的。
  2. 容易计算:从原数据计算出MD5值很容易。
  3. 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
  4. 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。

const crypto = require('crypto');
var content = 'content';
var md5 = crypto.createHash('md5');
md5.update(content);
md5.digest();
//返回 <Buffer 9a 03 64 b9 e9 9b b4 80 dd 25 e1 f0 28 4c 85 55>

/*
md5.digest('hex');
Error: Digest already called, 说明digest只能被一次调用
正常输出的情况:
'9a0364b9e99bb480dd25e1f0284c8555'
*/

Hmac加密算法

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。HMAC可以有效防止一些类似md5的彩虹表等攻击,比如一些常见的密码直接MD5存入数据库的,可能被反向破解。

定义HMAC需要一个加密用散列函数(表示为H,可以是MD5或者SHA-1)和一个密钥K。我们用B来表示数据块的字节数。(以上所提到的散列函数的分割数据块字长B=64),用L来表示散列函数的输出数据字节数(MD5中L=16,SHA-1中L=20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比B大,则首先用使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用的密钥。一般情况下,推荐的最小密钥K长度是L个字节。

下面为我在项目中使用到的Hmac加密(采用sha1方式):(由于密钥会通过随机生成的16位数进行加密后再对明文加密,每次生成的新密钥(token)都不同,所以最后生成的密文也不会相同,这种加密不可逆,

即使为md5方式,也难以通过彩虹表来攻击

const crypto = require('crypto');
var content = 'content';
var secretKey = crypto.randomBytes(16).toString('hex');
crypto.createHmac('sha1', secretKey).update(content).digest().toString('base64');
//返回 'NRhAYSJFAlL9w5OCmjTveWGMlVI='

密钥加盐

我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码。

盐(Salt),在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。加盐后的散列值,可以极大的降低由于用户数据被盗而带来的密码泄漏风险,即使通过彩虹表寻找到了散列后的数值所对应的原始内容,但是由于经过了加盐,插入的字符串扰乱了真正的密码,使得获得真实密码的概率大大降低。

如果不加盐,由于用户密码位数不足,短密码的散列结果很容易被彩虹表破解,非常不安全,因此通常在用户的密码末尾添加特定的字符(俗称:盐),加盐之后的密码位数更长了,散列值也发生了变化,因此不容易被破解。

PBKDF2应用一个伪随机函数以导出密钥。导出密钥的长度本质上是没有限制的。(但是,导出密钥的最大有效搜索空间受限于基本伪随机函数的结构。)对新的应用推荐使用PBKDF2。

PBKDF生成函数分为异步和同步两种

 1. crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)

 2. crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)

Provides an asynchronous Password-Based Key Derivation Function 2 (PBKDF2) implementation. A selected HMAC digest algorithm specified by digest is applied to derive a key of the requested byte length (keylen) from the password, salt and iterations.

The supplied callback function is called with two arguments: err and derivedKey. If an error occurs, err will be set; otherwise err will be null. The successfully generated derivedKey will be passed as a Buffer.

The iterations argument must be a number set as high as possible. The higher the number of iterations, the more secure the derived key will be, but will take a longer amount of time to complete.

The salt should also be as unique as possible. It is recommended that the salts are random and their lengths are greater than 16 bytes. See NIST SP 800-132 for details.

PBJDF2 提供了一个异步的基于密码的密钥生成函数的实现。一个选中的HMAC摘要算法被用于根据密码、盐和迭代次数导出指定的字节长度(keylen)的密钥。

提供的回调函数在被调用时会携带2个参数:错误信息和导出的密钥。如果一个错误信息产生,错误参数就将会被设置,否则错误参数为空。如果成功产生了一个密钥,将会被当做一个字节数组。

迭代参数必须是一个尽可能大的数字,迭代参数的数值越大,导出的密钥越安全,但是会花掉更长的时间来完成这项操作。

盐也应该尽可能的独特。建议随机生成盐,并且盐的长度要大于16字节。详细请参阅 NIST SP 800-132。

const crypto = require('crypto');
var keyLen = 16; //生成的密钥长度, 单位字节
crypto.pbkdf2('secret', 'salt', 100000, keyLen, 'sha1', (err, key) => {
    if(err) throw err;
    console.log(key.toString('hex'));
});
//输出 0e24bc5a548b236e3eb3b22317ef8056

对称加密算法

对称加密算法的原理很容易理解,通信一方用KEK加密明文,另一方收到之后用同样的KEY来解密就可以得到明文。

1、异或加密算法

明文与密钥进行一次 异或 (记做㊉ ) 运算将成为密文,密文再与密钥进行一次异或运算将还原为明文。

var key = 0b11111111;
var num = 0x77;
var encrypted = key ^ num;
//返回 139 = 0x8B
var decrypted = encrypted ^ key;
//返回 119 = 0x77

2、分组加密算法

分组长度可以在 128/196/256 比特中进行选择(即一轮可加密这么多比特的明文生成同样长度的密文,一次加密可能需要迭代多轮)。

分组密码算法只能加密固定长度的分组,但是我们需要加密的明文长度可能会超过分组密码的分组长度,这时就需要对分组密码算法进行迭代,以便将一段很长的明文全部加密。而迭代的方法就称为分组密码的模式。

模式有很多种类,分组密码的主要模式有:

  • ECB 模式:Electronic Codebook mode (电子密码本模式)
  • CBC 模式:Cipher Block Channing mode(密码分组链接模式)
  • CFB 模式:Cipher FeedBack mode (密文反馈模式)
  • OFB 模式:Output FeedBack mode(输出反馈模式)
  • CTR 模式:CounTeR mode(计数器模式)

这几种模式的运作流程这里不做赘述,只需知道:

  • ECB过于简单而不安全,已被弃用;
  • CFB可被施以重放攻击;
  • OFB 和 CTR 都可被主动攻击者反转密文,而引起解密后明文中的相应比特也发生变化;CTR比之OFB,多出能支持并发计算的特性,此外CTR是流式密码;
  • CBC虽不支持并行计算,但是却是这些模式中最为安全的

详细请参看 http://blog.csdn.net/chy555chy/article/details/51620291

const crypto = require('crypto');
crypto.getCiphers();
/*
返回支持的加密算法
[ 'CAST-cbc',
  'aes-128-cbc',
  'aes-128-cbc-hmac-sha1',
  'aes-128-cfb',
  'aes-128-cfb1',
  'aes-128-cfb8',
  'aes-128-ctr',
  'aes-128-ecb',
  'aes-128-gcm',
  'aes-128-ofb',
  'aes-128-xts',
  'aes-192-cbc',
  'aes-192-cfb',
  'aes-192-cfb1',
  'aes-192-cfb8',
  'aes-192-ctr',
  'aes-192-ecb',
  'aes-192-gcm',
  'aes-192-ofb',
  'aes-256-cbc',
  'aes-256-cbc-hmac-sha1',
  'aes-256-cfb',
  'aes-256-cfb1',
  'aes-256-cfb8',
  'aes-256-ctr',
  'aes-256-ecb',
  'aes-256-gcm',
  'aes-256-ofb',
  'aes-256-xts',
  'aes128',
  'aes192',
  'aes256',
  'bf',
  'bf-cbc',
  'bf-cfb',
  'bf-ecb',
  'bf-ofb',
  'blowfish',
  'camellia-128-cbc',
  'camellia-128-cfb',
  'camellia-128-cfb1',
  'camellia-128-cfb8',
  'camellia-128-ecb',
  'camellia-128-ofb',
  'camellia-192-cbc',
  'camellia-192-cfb',
  'camellia-192-cfb1',
  'camellia-192-cfb8',
  'camellia-192-ecb',
  'camellia-192-ofb',
  'camellia-256-cbc',
  'camellia-256-cfb',
  'camellia-256-cfb1',
  'camellia-256-cfb8',
  'camellia-256-ecb',
  'camellia-256-ofb',
  'camellia128',
  'camellia192',
  'camellia256',
  'cast',
  'cast-cbc',
  'cast5-cbc',
  'cast5-cfb',
  'cast5-ecb',
  'cast5-ofb',
  'des',
  'des-cbc',
  'des-cfb',
  'des-cfb1',
  'des-cfb8',
  'des-ecb',
  'des-ede',
  'des-ede-cbc',
  'des-ede-cfb',
  'des-ede-ofb',
  'des-ede3',
  'des-ede3-cbc',
  'des-ede3-cfb',
  'des-ede3-cfb1',
  'des-ede3-cfb8',
  'des-ede3-ofb',
  'des-ofb',
  'des3',
  'desx',
  'desx-cbc',
  'id-aes128-GCM',
  'id-aes192-GCM',
  'id-aes256-GCM',
  'idea',
  'idea-cbc',
  'idea-cfb',
  'idea-ecb',
  'idea-ofb',
  'rc2',
  'rc2-40-cbc',
  'rc2-64-cbc',
  'rc2-cbc',
  'rc2-cfb',
  'rc2-ecb',
  'rc2-ofb',
  'rc4',
  'rc4-40',
  'rc4-hmac-md5',
  'seed',
  'seed-cbc',
  'seed-cfb',
  'seed-ecb',
  'seed-ofb' ]
*/

//非对称加密
var content = 'content';
var key = 'key';
var encrypted = '', decrypted = '';
var cipher = crypto.createCipher('aes192', key);
encrypted += cipher.update(content, 'binary', 'hex');
//返回 ''
encrypted += cipher.final('hex');
//返回 'ae645028b381c6b7b31a2fe94e882053'

//非对称解密
var decipher = crypto.createDecipher('aes192', key);
decrypted += decipher.update(encrypted, 'hex', 'binary');
//返回 ''
decrypted += decipher.final('binary');
//返回 content

非对称加密算法

不对称加密算法,使用两把完全不同但又是完全匹配的一对Key:公钥和私钥。在使用不对称加密算法加密文件时,只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。

非对称加密等寡人阅读完openssl模块再另行补充
尝鲜请阅读该链接 http://ju.outofmemory.cn/entry/118198

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值