nodeJS之crypto模块md5和Hmac加密
nodeJS之crypto模块md5和Hmac加密
原文地址:https://www.cnblogs.com/tugenhua0707/p/9128690.html
在nodejs中,可以使用crypto模块来实现各种不同的加密与解密处理,在crypto模块中包含了类似MD5或SHA-1这些散列算法,我们可以通过crypto模块来实现HMAC运算。
什么是HMAC运算?
HMAC的中文意思是:散列运算消息认证码;运算使用散列算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。HMAC运算可以用来验证两段数据是否匹配,以确认该数据没有被篡改。
在crypto模块中,为每一种加密算法定义了一个类。可以使用getCiphers方法来查看nodejs中能够使用的所有加密算法。该方法返回一个数组,包括了nodejS中能够使用的所有散列算法。使用方法如下所示:
const crypto = require('crypto');
console.log(crypto.getCiphers());
/*
输出如下
[ 'aes-128-cbc',
'aes-128-cbc-hmac-sha1',
'aes-128-cbc-hmac-sha256',
'aes-128-ccm',
'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-ccm',
'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-cbc-hmac-sha256',
'aes-256-ccm',
'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-CCM',
'id-aes128-GCM',
'id-aes128-wrap',
'id-aes192-CCM',
'id-aes192-GCM',
'id-aes192-wrap',
'id-aes256-CCM',
'id-aes256-GCM',
'id-aes256-wrap',
'id-smime-alg-CMS3DESwrap',
'idea',
... 19 more items ]
*/
一:散列算法
散列(也可以叫哈希)算法,它是用来对一段数据进行验证前,将该数据模糊化,或者也可以为一大段数据提供一个校验码。
在nodejs中,为了使用该散列算法,我们先要使用 createHash方法创建一个hash对象。使用方法如下:
crypto.createHash(params);
在如上方法中,需要使用一个参数,其参数值为一个在Node.js中可以使用的算法,比如 'sha1', 'md5', 'sha512' 等等这样的,用于指定需要使用的散列算法,该方法返回被创建的hash对象。
在创建完hash对象后,可以通过使用该对象的update方法创建一个摘要。该方法的使用方式如下:
hash.update(data, [encoding]);
在如上面的方法,该方法需要使用两个参数,第一个参数是必选项,该参数值是一个Buffer对象或一个字符串,用于指定摘要内容; 第二个参数 encoding用于指定摘要内容所需使用的编码格式,可以指定为 'utf-8', 'ascii', 或 'binary'. 如果不使用第二个参数,则第一个参数data参数值必须为一个Buffer对象,我们也可以在摘要被输出前使用多次updata方法来添加摘要内容。
在第一步创建了一个hash对象后,第二步就是添加摘要内容,那么第三步我们就是使用hash对象的digest方法来输出摘要内容了;在使用hash对象的digest
方法后,不能再向hash对象中追加摘要内容,也就是说你使用了digest方法作为输出后,你再追加内容也不会执行,因此是不能向hash对象中追加内容。
使用方法如下:
hash.digest([encoding]);
该方法有一个参数,该参数是一个可选值,表示的意思是 用于指定输出摘要的编码格式,可指定参数值为 'hex', 'binary', 及 'base64'.如果使用了该参数,那么digest方法返回字符串格式的摘要内容,如果不使用该参数,那么digest方法返回一个是Buffer对象。
二:MD5算法
MD5是计算机领域使用最广泛的散列函数(可以叫哈希算法、摘要算法),注意是用来确保消息的完整和一致性。
下面我们最主要是以 md5 加密为例来了解下加密算法。
MD5算法有以下特点:
1. 压缩性: 任意长度的数据,算出的MD5值长度都是固定的。
2. 容易计算:从原数据算出MD5值很容易。
3. 抗修改性:对原数据进行任何改动,哪怕只修改一个字节,所得到的MD5值都有很大的区别。
4. 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同的MD5值的伪数据是非常困难的。
MD5的作用是让大容量信息在用数字签名软件签署私人秘钥前被压缩成一种保密的格式(就是把任意长度的字符串变换成一定长的十六进制数字串)。
如下使用代码:
const crypto = require('crypto'); const str = 'abc'; // 创建一个hash对象
const md5 = crypto.createHash('md5'); // 往hash对象中添加摘要内容
md5.update(str); // 使用 digest 方法输出摘要内容,不使用编码格式的参数 其输出的是一个Buffer对象
// console.log(md5.digest());
// 输出 <Buffer 90 01 50 98 3c d2 4f b0 d6 96 3f 7d 28 e1 7f 72> // 使用编码格式的参数,输出的是一个字符串格式的摘要内容
console.log(md5.digest('hex')); // 输出 900150983cd24fb0d6963f7d28e17f72
Md5算法demo实列:
现在我们来看下一个demo,比如一些登录信息,比如密码直接以明文的方式存放在数据库中是不安全的,开发人员直接可以通过肉眼就可以知道,可以记下来,因此我们需要使用md5来加密一下;因此我们可以做如下代码加密:
const crypto = require('crypto'); var cryptoPassFunc = function(password) {
const md5 = crypto.createHash('md5');
return md5.update(password).digest('hex');
}; const password = '123456';
const croptyPass = cryptoPassFunc(password); const croptyPass2 = cryptoPassFunc(password); console.log(croptyPass); // e10adc3949ba59abbe56e057f20f883e console.log(croptyPass2); // e10adc3949ba59abbe56e057f20f883e
如上console.log输出的是通过md5加密后代码了;
只对md5加密的缺点:
通过上面对md5加密后确实比明文好很多,至少很多人直接使用肉眼看到的并记不住,也不知道密码多少,但是只对md5加密也存在缺点,如上代码使用console.log打印两次后,加密后的代码是一样,也就是说 相同的明文密码,加密后,输出两次,md5的值也是一样的。 所以这样也是不安全的。
密码加盐:
什么意思呢?就是在密码的特定位置上插入特定的字符串后,再对修改后的字符串进行md5加密,这样做的好处是每次调用代码的时候,插入的字符串不一样,会导致最后的md5值会不一样的。代码如下:
const crypto = require('crypto'); var saltPasswordFunc = function(password, salt) { // 密码加盐
const saltPassword = password + ':' + salt;
console.log('原始密码:%s', password);
console.log('加盐后的密码:%s', saltPassword); const md5 = crypto.createHash('md5');
const result = md5.update(saltPassword).digest('hex');
console.log('加盐密码后的md5的值为:%s', result); }; const password = '123456'; saltPasswordFunc(password, 'abc');
/*
输出结果为:
原始密码:123456
加盐后的密码:123456:abc
加盐密码后的md5的值为:51011af1892f59e74baf61f3d4389092
*/ saltPasswordFunc(password, 'def');
/*
输出结果为:
原始密码:123456
加盐后的密码:123456:def
加盐密码后的md5的值为:5091d17d6b08ba9a95ccef51f598b249
*/
密码加密:随机盐值
如上通过密码加盐,比单单的使用md5加密,安全性相对来说更高点,但是也存在问题,比如字符串拼接算法中的字符串开发者知道的,第二个是盐值固定,也就是说拼接的字符串的盐值是固定的;所以存在这几个问题,因此下面我们需要一个随机数来生成随机盐值。这样安全性或许会更高点。
因此优化后的代码如下:(优化点无非就是生成一个随机数当做盐值)
const crypto = require('crypto'); var getRandomSalt = function() {
// 使用六位随机数吧
const randomSalt = Math.random().toString().slice(2, 8);
console.log(randomSalt);
return randomSalt;
}; var saltPasswordFunc = function(password, salt) {
// 密码加盐
const saltPassword = password + ':' + salt;
console.log('原始密码:%s', password);
console.log('加盐后的密码:%s', saltPassword); const md5 = crypto.createHash('md5');
const result = md5.update(saltPassword).digest('hex');
console.log('加盐密码后的md5的值为:%s', result);
}; const password = '123456'; saltPasswordFunc(password, getRandomSalt());
/*
输出结果为:
原始密码:123456
加盐后的密码:123456:随机生成6位数字
加盐密码后的md5的值为:密码+ ':' + 随机生成6位数字 的md5值
*/ saltPasswordFunc(password, getRandomSalt());
/*
输出结果为:
原始密码:123456
加盐后的密码:123456:随机生成6位数字
加盐密码后的md5的值为:密码+ ':' + 随机生成6位数字 的md5值
*/
这样做的好处是:每次运行的时候,或者说叫请求的时候,盐值是不一样的,导致每次生成的md5加密后的密码是不一样的。
三:HMAC算法
HMAC算法是将散列算法与一个密钥结合在一起,以阻止对签名完整性破坏,其实就是类似于上面的提到的md5密码中加盐道理是类似的。
使用HMAC算法前,我们使用createHmac方法创建一个hmac对象,创建方法如下所示:
crypto.createHmac(params, key);
该方法中使用两个参数,第一个参数含义是在Node.js中使用的算法,比如'sha1', 'md5', 'sha256', 'sha512'等等,该方法返回的是hmac对象。
key参数值为一个字符串,用于指定一个PEM格式的密钥。
在创建完成hmac对象后,我们也是一样使用一个update方法来创建一个摘要,该方法使用如下所示:
hmac.update(data);
在update方法中,使用一个参数,其参数值为一个Buffer对象或一个字符串,用于指定摘要内容。也是一样可以在被输出之前使用多次update方法来添加摘要内容。
最后一步就是 使用hmac对象的digest方法来输出摘要内容了;在使用hmac对象的digest方法后,不能再向hmac对象中追加摘要内容,也就是说你使用了digest方法作为输出后,因此是不能向hmac对象中追加内容。使用方法如下:
hmac.digest([encoding]);
该方法有一个参数,该参数是一个可选值,表示的意思是 用于指定输出摘要的编码格式,可指定参数值为 'hex', 'binary', 及 'base64'.
如果使用了该参数,那么digest方法返回字符串格式的摘要内容,如果不使用该参数,那么digest方法返回一个是Buffer对象。
如下使用一个简单的demo
const crypto = require('crypto'); // 创建一个hmac对象
const hmac = crypto.createHmac('md5', 'abc'); // 往hmac对象中添加摘要内容
const up = hmac.update('123456'); // 使用 digest 方法输出摘要内容 const result = up.digest('hex'); console.log(result); // 8c7498982f41b93eb0ce8216b48ba21d
nodeJS之crypto模块md5和Hmac加密的更多相关文章
- nodeJS之crypto模块公钥加密及解密
nodeJS之crypto模块公钥加密及解密 NodeJS有以下4个与公钥加密相关的类.1. Cipher: 用于加密数据:2. Decipher: 用于解密数据:3. Sign: 用于生成签名:4. ...
- BASE64,MD5,SHA,HMAC加密與解密算法(java)
package com.ice.webos.util.security; import java.io.UnsupportedEncodingException; import java.math.B ...
- 使用nodeJS的 crypto模块来为你的密码hash加盐
这篇文章将向你解释如何使用Node.js的Crypto模块对你的密码进行加盐hash.在这里,我们将不会对不懂的密码存储方式进行详细的比较.我们将要做的是知道在Node.js中使用加盐hash在进行密 ...
- 浅析nodeJS中的Crypto模块,包括hash算法,HMAC算法,加密算法知识,SSL协议
node.js的crypto在0.8版本,这个模块的主要功能是加密解密. node利用 OpenSSL库(https://www.openssl.org/source/)来实现它的加密技术, 这是因为 ...
- 使用crypto模块实现md5加密功能(解决中文加密前后端不一致的问题)
正常情况下使用md5加密 var crypto = require('crypto'); var md5Sign = function (data) { var md5 = crypto.create ...
- Nodejs进阶:MD5入门介绍及crypto模块的应用
本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址.欢迎加群交流,群号 197339705. 简介 MD5(Message-Digest Algorithm) ...
- Nodejs:md5入门介绍及crypto模块的应用
简介 MD5(Message-Digest Algorithm)是计算机安全领域广泛使用的散列函数(又称哈希算法.摘要算法),主要用来确保消息的完整和一致性.常见的应用场景有密码保护.下载文件校验等. ...
- nodeJS之crypto加密
前面的话 加密模块提供了 HTTP 或 HTTPS 连接过程中封装安全凭证的方法.也提供了 OpenSSL 的哈希,hmac, 加密(cipher), 解密(decipher), 签名(sign) 和 ...
- Nodejs进阶:crypto模块中你需要掌握的安全基础
本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址. 一. 文章概述 互联网时代,网络上的数据量每天都在以惊人的速度增长.同时,各类网络安全问题层出不穷.在信 ...
随机推荐
- List-ArrayList集合基础增强底层源码分析
List集合基础增强底层源码分析 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 集合分为三个系列,分别为:List.set.map List系列 特点:元素有序可重复 有序指的是元素的 ...
- SpringBoot整合系列-整合MyBatis
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9971036.html SpringBoot整合Mybatis 步骤 第一步:添加必要的j ...
- Oracle闪回表
Oracle闪回技术 场景:测试环境数据库的表数据被误删除. 解决思路:使用闪回表技术 原理 闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小 ...
- 大前端的自动化工厂(1)——Yeoman
一.Yeoman是什么 Yeoman是现代化前端项目的脚手架工具,用于生成包含指定框架结构的工程化目录结构.它是整个前端自动化工厂的第一站. 从个人使用者的角度来看,Yeoman的地位有些鸡肋,因为流 ...
- Java开发笔记(六十一)Lambda表达式
前面介绍了匿名内部类的简单用法,通过在sort方法中运用匿名内部类,不但能够简化代码数量,还能保持业务代码的连续性.只是匿名内部类的结构仍显啰嗦,虽然它省去了内部类的名称,但是花括号里面的方法定义代码 ...
- MongoDB初了解——用户权限
本文所述MongoDB版本为4.0.5,笔者对MongoDB刚接触,对各个版本的MongoDB不甚了解,本文不对该版本的MongoDB做特性介绍,所涉及命令也许对其余版本不适用. 因为目前有一个试验性 ...
- 程序员50题(JS版本)(三)
程序11:判断101~200之间有多少个素数,并输出所有素数 for(var i=101,num=0;i<=200;i++){ for(var j=2;j<=i;j++){ if(i%j= ...
- mac IDE输入光标变成块状 改为竖线
mac下安装IDE后,出现“输入光标变成块状”的情况,是因为安装的时候装了ideaVim插件,改为竖线光标的方法:把ideaVim插件去掉
- Vue:如何在地图上添加自定义覆盖物(点)
目录 如何在地图上添加自定义覆盖物(点) 首发日期:2019-1-25 如何在地图上添加自定义覆盖物(点) 此文重点是在地图上标点,所以就省去引入百度地图的步骤了. 先给一下最终的效果. 这个效果主要 ...
- USGS-EROS项目espa-surface-reflectance中的Landsat8 大气校正LaSRC Version 1.3.0模块利用vs2010编译出windows64位版本(四)
,支持一些关键问题: 1 数据初始化问题.该问题是指在linux环境下编程标准c并编译,用户定义的变量默认初始值是0,但在windows 64 win7环境中,变量默认初始值是负值极小.... ...