🖥️ NodeJS专栏:Node.js从入门到精通
🖥️ 博主的前端之路:前端之行,任重道远(来自大三学长的万字自述)
🧧 个人社区:海底烧烤店ai(从前端到全栈)
🧑💼个人简介:即将大三的学生,一个不甘平庸的平凡人🍬
👉 你的一键三连是我更新的最大动力❤️!
📑 文章目录
✍️ 前言
crypto
模块的目的是为了提供通用的加密和哈希算法。用纯
JavaScript
代码实现这些功能不是不可能,但速度会非常慢。
Nodejs
用
C/C++
实现这些算法后,通过
cypto
这个模块暴露为
JavaScript
接口,这样用起来方便,运行速度也快。
这篇我们将上手
crypto
模块来实现数据加密,让我们开始吧!
一、哈希算法
哈希算法(又称散列算法或者消息摘要算法)是信息存储和查询所用的一项基本技术。
它是一种基于
Hash
函数的文件构造方法,可实现对记录的快速随机存取。
它把给定的任意长度的关键宇映射为一个固定长度的哈希值,一般用于
鉴权
、
认证
、
加密
、
索引
等。其主要优点是运算简单,预处理时间较短,内存消耗低,匹配查找速度比较快,便于维护和刷新,支持匹配规则数多等。
常见的哈希算法的有
md5
,
sha1
等。
🔐 MD5
MD5
是一种常用的哈希算法,用于给任意数据一个“
签名
”(也称
摘要
),这个签名通常用一个十六进制的字符串表示。
我们引入
crypto
模块,使用
MD5
构造一个
hash
对象:
// 引入crytoconst crypto =require("crypto");// 用md5创建HASH对象const hash = crypto.createHash("md5");
我们创建的这个
hash
对象中有以下方法:
update
:用给定的data
数据更新哈希内容digest
:计算传递给哈希(使用hash.update()
方法)的所有数据的摘要(也可理解为加密结果)
**使用
update
添加需要加密的数据:**
hash.update("Ailjx");
在数据输出前(调用
digest
前)
update
可以多次调用,用来添加多个需要加密的数据,但最后输出时只是输出了多个数据合并后加密的结果
update
具有第二个可选参数,可指定第一个参数为字符串时的的编码格式,
update
方法默认字符串编码为
UTF-8
,第一个参数也可传递Buffer对象(此时第二个参数将失效)
**使用
digest
获得加密后的结果:**
const crypto =require("crypto");const hash = crypto.createHash("md5");
hash.update("Ailjx");
console.log(hash.digest("hex"));// 01f4c7226395e3f9b6713b2fea94ea69
digest
接收的参数代表编码格式,有以下四种:
hex
编码也称之为
Base16
编码,就是把一个字节,用十六进制来表示
使用
digest
之后不能再使用
update
方法向
HASH
对象添加需要加密的数据。
**
update
和
digest
能够直接链式调用:**
const crypto =require("crypto");const hash = crypto.createHash("md5");
console.log(hash.update("Ailjx").digest("hex"));// 01f4c7226395e3f9b6713b2fea94ea69
如果要计算
SHA1
,只需要把上面
createHash
中的
'md5'
改成
'sha1'
即可
❗️ 问题
向
MD5
这样的哈希算法并不能算是真正意义上的加密算法,因为通过
MD5
编码后的数据是可以通过解码来获得原数据的,网上也有很多
MD5
解密的工具,这就是为什么官方称
MD5
为
信息摘要算法
而非
信息加密算法
。
而下面讲到
Hmac
算法,则是通过添加一个密钥来实现真正意义上的加密。
二、Hmac算法
Hmac
算法也是一种哈希算法,它可以利用
MD5
或
SHA1
等哈希算法,不同的是,Hmac还需要一个密钥。
通过
createHmac
方法创建一个
Hmac
对象,
createHmac
接受三个参数:
algorithm
:取决于平台上OpenSSL
版本支持的可用算法。例如’sha256
’,‘sha512
’,'md5
’等key
:用于生成加密HMAC
哈希的HMAC
密钥options
: 可选的配置对象 -encoding
当key
是字符串时使用的字符串编码
const crypto =require("crypto");const key ="Ailjx-key";const hmac = crypto.createHmac("sha256", key);// 添加加密数据
hmac.update("Hello, world!");
console.log(hmac.digest("hex"));// 6cc6637baf26a4b3f781c27bdcfd9deb9e08de7d1cb3ee86802f9114ae3fef39
只要密钥发生了变化,那么同样的输入数据也会得到不同的签名,因此,可以把
Hmac
理解为用随机数“增强”的哈希算法
三、对称加密算法
AES
是一种常用的对称加密算法,加解密都用同一个密钥。
crypto
模块提供了
AES
支持,但是需要自己封装好函数,便于使用。
🔒 加密方法
crypto.createCipheriv()
方法用于创建 **
Cipher
实例,这个实例用于加密数据**。
createCipheriv
方法接受三个参数:
algorithm
用于指定加密算法,如aes-128-ecb
、aes-128-cbc
等;key
是用于加密的密钥iv
参数可选,用于指定加密时所用的向量> 向量和具体加密模式有关,使用>> cbc>
> ,>> ofb>
> 、>> cfb>
> 时>> iv>
> 向量是必须的,>> CBC>
> 模式或>> CFB>
> 模式必须保证每次加密的>> IV>
> 是安全随机数,>> ecb>
> 时就不需要设置向量,>> iv>
> 参数设置为null 即可> 注意这里的>> key>
> 密钥必须是8/16/32位,如果加密算法是128,则对应的密钥是16位,如果加密算法是256,则对应的密钥是32位,iv向量与key密钥长度相等
createCipheriv
方法返回的Cipher实例具有方法
update
和
final
cipher.update
方法具有以下参数:-data
用于加密的数据-inputEncoding
数据的编码-outputEncoding
返回值的编码,若该参数不存在,则返回Buffer对象格式> 该>> cipher.update()>
> 方法可以使用新数据多次调用,直到 cipher.final()被调用cipher.final
方法具有一个可选的参数,代表返回值的编码,若不填该参数,则返回Buffer对象格式> 一旦调用了>> cipher.final()>
> ,该>> Cipher>
> 对象就不能再用于加密数据。尝试多次调用>> cipher.final()>
> 将导致抛出错误
手写加密函数:
const crypto =require("crypto");// 加密方法functionencrypt(key, iv, data){// 使用aes-128-cbc算法进行加密let decipher = crypto.createCipheriv("aes-128-cbc", key, iv);// utf-8 代表输入数据的编码格式,hex(十六进制)代表输出数据的格式,加decipher.final("hex")代表结束了return decipher.update(data,"utf-8","hex")+ decipher.final("hex");}
🔓 解密方法
crypto.createDecipheriv()
方法用于创建 **
Decipher
实例**,这个实例用于解密数据。
crypto.createDecipheriv()
方法与
createCipheriv
方法一样接受三个参数,参数含义也相同。
Decipher
实例也与
Cipher
实例一样具有方法
update
和
final
手写解密方法:
const crypto =require("crypto");// 解密方法functiondecrypt(key, iv, crypted){// 使用aes-128-cbc算法进行加密就需要使用aes-128-cbc算法进行解密let decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);// 输入hex格式输出utf8格式return decipher.update(crypted,"hex","utf-8")+ decipher.final("utf-8");}
🔍 应用
const crypto =require("crypto");// 加密方法functionencrypt(key, iv, data){// 使用aes-128-cbc算法进行加密let decipher = crypto.createCipheriv("aes-128-cbc", key, iv);// utf-8 代表输入数据的编码格式,hex(十六进制)代表输出数据的格式,加decipher.final("hex")代表结束了return decipher.update(data,"utf-8","hex")+ decipher.final("hex");}// 解密方法functiondecrypt(key, iv, crypted){// 使用aes-128-cbc算法进行加密就需要使用aes-128-cbc算法进行解密let decipher = crypto.createDecipheriv("aes-128-cbc", key, iv);// 输入hex格式输出utf8格式return decipher.update(crypted,"hex","utf-8")+ decipher.final("utf-8");}// -----------------------------------------------------------------// 因为使用的是aes-128-cbc 128位的加密算法// 所以key,iv必须是16个字节(一个字节8位,16*8=128)const key ="abcdef0123456789";// 随便写16个字节const iv ="1234567890abcdef";// 随便写16个字节// 需要加密的数据let data ="Ailjx";let cryted =encrypt(key, iv, data);
console.log("加密结果:", cryted);// 加密结果: 779c901e75dfefdc1e88077f422572eelet decrypted =decrypt(key, iv, cryted);
console.log("解密结果:", decrypted);// 解密结果: Ailjx
📒 结语
关于
node.js
的更多内容请移步我的
node.js
专栏:Node.js从入门到精通
关注博主,订阅专栏,学习前端不迷路!
如果本篇文章对你有所帮助,还请客官一件四连!❤️
版权归原作者 海底烧烤店ai 所有, 如有侵权,请联系我们删除。