NodeJS的加密方法

NodeJS加密模块允许使用加密的功能,NodeJS加密模块通过使用require('crypto')来访问。crypto 模块提供了加密功能,包含对 OpenSSL 的哈希、HMAC、加密、解密、签名以及验证功能的一整套封装,核心模块,使用时不需安装。

所谓加密是以某种算法改变原有的信息数据,使得未授权用户即使获得了已加密信息,因不知解密的方法,无法得知信息真正的含义,通过这种方式提高网络数据传输的安全性,加密算法常见的有哈希算法、HMAC 算法、签名、对称性加密算法和非对称性加密算法,加密算法也分为可逆和不可逆,比如 md5 就是不可逆加密,只能暴力破解(撞库)。

crypto模块

NodeJS中通过引入crypto来进行访问加密。

const crypto = require('crypto')
console.log(crypto)  
//打印出crypto模块中包含的所有属性,其中就包括常用的createHash、createHmac等加密方法
// 返回支持的加密算法名数组。
const ciphers = crypto.getCiphers()

// 返回支持的哈希算法名数组。
const hashes = crypto.getHashes()
console.log(hashes)
//[
  'RSA-MD4',      
  'RSA-MD5',      
  'RSA-MDC2',     
  'RSA-RIPEMD160',
  'RSA-SHA1',     
  'RSA-SHA1-2',   
  'RSA-SHA224',
  'RSA-SHA256',
  'RSA-SHA3-224',
  'RSA-SHA3-256',
  'RSA-SHA3-384',
  'RSA-SHA3-512',
  'RSA-SHA384',
  'RSA-SHA512',
  'RSA-SHA512/224',
  'RSA-SHA512/256',
  'RSA-SM3',
  'blake2b512',
  'blake2s256',
  'id-rsassa-pkcs1-v1_5-with-sha3-224',
  'id-rsassa-pkcs1-v1_5-with-sha3-256',
  'id-rsassa-pkcs1-v1_5-with-sha3-384',
  'id-rsassa-pkcs1-v1_5-with-sha3-512',
  'md4',
  'md4WithRSAEncryption',
  'md5',
  'md5-sha1',
  'md5WithRSAEncryption',
  'mdc2',
  'mdc2WithRSA',
  'ripemd',
  'ripemd160',
  'ripemd160WithRSA',
  'rmd160',
  'sha1',
  'sha1WithRSAEncryption',
  'sha224',
  'sha224WithRSAEncryption',
  'sha256',
  'sha256WithRSAEncryption',
  'sha3-224',
  'sha3-256',
  'sha3-384',
  'sha3-512',
  'sha384',
  'sha384WithRSAEncryption',
  'sha512',
  'sha512-224',
  'sha512-224WithRSAEncryption',
  'sha512-256',
  'sha512-256WithRSAEncryption',
  'sha512WithRSAEncryption',
  'shake128',
  'shake256',
  'sm3',
  'sm3WithRSAEncryption',
  'ssl3-md5',
  'ssl3-sha1',
  'whirlpool'
]

哈希算法(Hash)

哈希算法也叫散列算法,用来把任意长度的输入变换成固定长度的输出,常见的有 'sha1''md5''sha256''sha512' 等。

md5

md5 是开发中经常使用的算法之一。它具有不可逆;不管加密的内容多长,最后输出的结果长度都相等;内容不同输出的结果完全不同,内容相同输出的结果完全相同的特点。

由于相同的输入经过 md5 加密后返回的结果完全相同,所以破解时通过 “撞库” 进行暴力破解,当连续被 md5 加密 3 次以上时就很难被破解了,所以使用 md5 一般会进行多次加密。

const crypto = require('crypto')
// createHash() 创建加密方式
// update() 要加密的内容
// digest() 加密后输出结果,不传参默认返回加密后的 Buffer,常用的参数有 hex、Base64和binary, hex 代表十六进制,加密后长度为 32,Base64 的结果长度为 24,以 == 结尾。
let md5Text1 = crypto.createHash('md5')
 .update("love")
 .digest()
let md5Text2 = crypto.createHash('md5')
 .update("love")
 .digest("base64")
console.log(md5Text1) // <Buffer b5 c0 b1 87 fe 30 9a f0 f4 d3 59 82 fd 96 1d 7e>
console.log(md5Text2) // tcCxh/4wmvD001mC/ZYdfg==

update 方法的返回值就是 this,即当前实例,所以支持链式调用,较长的信息也可以多次调用 update 方法进行分段加密,调用 digest 方法同样会返回整个加密后的值。

const crypto = require('crypto')
let md5Text3 = crypto.createHash('md5') 
 .update("lo")
 .update("ve")
 .digest("base64")
console.log(md5Text2) // tcCxh/4wmvD001mC/ZYdfg==

sha1

const crypto = require('crypto')
let shaText = crypto.createHash('sha1') 
 .update("love")
 .digest("hex")
console.log(md5Text2) // 9f2feb0f1ef425b292f2f94bc8482494df430413

Hmac算法

Hmac 算法又称加盐算法,是将哈希算法与一个密钥结合在一起,用来阻止对签名完整性的破坏,同样具备 md5 加密的几个特点。

let password = '123'
let hmacText1 = crypto.createHmac('sha1',password)
.update("love")
.digest('base64')
let hmacText2 = crypto.createHmac('sha1',password)
.update("love")
.digest('hex')

console.log(hmacText1) // WbuOiMJPQ6q+tQXpL10bJEv/0E4=
console.log(hmacText2) // 59bb8e88c24f43aabeb505e92f5d1b244bffd04e

crytpo.createHmac 第一个参数同 crytpo.createHash,为加密的算法,常用 sha1sha256,第二个参数为密钥。

digest 方法生成的加密结果长度要大于 md5hex 生成的结果长度为 64Base64 生成的结果长度为 44,以 = 结尾。

安全性高于 md5,通过密钥来加密,不知道密钥无法破解,缺点是密钥传输的过程容易被劫持,可以通过一些生成随机密钥的方式避免

对称性加密(Cipher)(官方已弃用)

对称性加密是发送数据时使用密钥和加密算法进行加密,接收数据时需要使用相同的密钥和加密算法的逆算法(解密算法)进行解密,也就是说对称性加密的过程是可逆的,crytpo 中使用的算法为 blowfish

本地生成SSH key秘钥

上面提到对称加密要用到秘钥,所以我们第一步应该生成秘钥。生成秘钥的方法有很多种,我们就以下为例,通过命令行来生成秘钥。

首先你可以你先看一下本地是否已经生成过秘钥:

~/.ssh 
bash: /c/Users/admin/.ssh: Is a directory //此时说明已经存在

如果没有生成,那你就可以通过一下命令来生成秘钥:

ssh-keygen -t rsa -C "your_email@example.com"

生成后你就可以在本地文件夹找到生成的 key 文件,一般包括 id_rsa.pub(公钥)和 id_rsa(私钥)两个文件夹。然后你就可以通过你喜欢的编辑工具来打开查看(默认情况下,生成秘钥在/c/Users/admin/.ssh文件夹内)。当然你也可以参考链接

createCipher加密

接着就可以通过crypto.createCipher 方法加密,使用 crypto.createDecipher 方法解密。但是使用的算法和密钥必须相同,需要注意的是解密过程中 update 中需要在第二个参数中指定加密时的格式,如 hex,在 final 还原数据时需要指定加密字符的编码格式,如 utf8

由于createCipher需要的秘钥是用来派生key 和IV,它必须是一个'binary'编码的字符串或者一个buffer。所以我们可以通过fs模块来获取一个buffer格式的秘钥。

const crypto = require('crypto')
const fs = require('fs')
const path = require('path')

//path.join(address,name) 第一个参数为文件地址,第二个为文件名称
let privateKey = fs.readFileSync(path.join('C:/Users/admin/.ssh',"id_rsa"))

// 加密
let cipher = crypto.createCipher("blowfish", privateKey);
cipher.update("love");

// final 方法不能链式调用
let result = cipher.final("hex");
console.log(result); // ff541470a00e5e04

// 解密
let decipher = crypto.createDecipher("blowfish", privateKey);
decipher.update(result, "hex");

let data = decipher.final("utf8");
console.log(data); // love

非对称性加密

非对称性加密相也是可逆的,较于对称性加密要更安全,消息传输方和接收方都会在本地创建一对密钥,公钥和私钥,互相将自己的公钥发送给对方,每次消息传递时使用对方的公钥加密,对方接收消息后使用他的的私钥解密,这样在公钥传递的过程中被截获也无法解密,因为公钥加密的消息只有配对的私钥可以解密。

const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
// 获取公钥和私钥
let publicKey = fs.readFileSync(path.join('C:/Users/admin/.ssh', "id_rsa.pub"));
let privateKey = fs.readFileSync(path.join('C:/Users/admin/.ssh',"id_rsa")); 

// 加密
let encodeData = crypto.publicEncrypt(publicKey, Buffer.from("love"));
//然然,加密传入的秘钥也可以是私钥,同样能解密出来,主要是在不方便公开的情况下,建议使用公钥
//let encodeData = crypto.publicEncrypt(privateKey, Buffer.from("love"));
// 解密
let decodeData = crypto.privateDecrypt(privateKey, encodeData);
console.log(decodeData.toString()); // love

签名sign

使用crypto.createSign()方法用于创建Sign实例。参数是要使用的哈希函数的字符串名称。不能使用关键字Sign直接创建对象。

const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
let publicKey = fs.readFileSync(path.join('C:/Users/admin/.ssh', "id_rsa.pub"));
let privateKey = fs.readFileSync(path.join('C:/Users/admin/.ssh',"id_rsa")); 

const sign = crypto.createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');
// console.log(signature)

// 验证签名
const verify = crypto.createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature, 'hex')); //true
// console.log(verify.verify(privateKey, signature, 'hex')); //true
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇