【加密】crypto/argon2
-
crypto不需要安装
- 是随Nodejs内核一起打包发布的
-
argon2安装
npm i -S argon2- 不需要封装到api_crypto.js中,而是直接使用
import * as argon2 from "argon2";const encrypt_password = await argon2.hash(password);await argon2.verify(user.password, password)
- 不需要封装到api_crypto.js中,而是直接使用
-
引入
import crypto from "crypto"; import config from "config"; import fs from "fs"; -
md5export const string2md5 = (s) => { if (!s || s.length === 0) return null; let md5 = createHash('md5'); return md5.update(s).digest('hex'); }; -
sha1export const string2sha1 = (s) => { if (!s || s.length === 0) return null; let sha1 = createHash('sha1'); return sha1.update(s).digest('hex'); }; -
pbkdf2export const pbkdf2Encrypt = async (password) => { return new Promise((resolve)=>{ pbkdf2(password, config.pbkdf2_salt, 4096, 512, 'sha256', (err, key) => { if (err) throw err; resolve(key.toString('hex')); }); }); }- 这个是异步函数
-
AES对称加密- 作用
- 对一些重要的隐私信息,用
密钥+iv写成加密串 - 把
iv:加密串存入数据库 - 就算数据库泄漏,没有服务器的
密钥,也无法解密
- 对一些重要的隐私信息,用
- 封装加密函数
const AES_ALGORITHM = 'aes-256-gcm'; const IV_LENGTH = 16; export const AESEncrypt = (text) => { if (!text || text.length === 0) return null; let iv = randomBytes(IV_LENGTH); let cipher = createCipheriv(AES_ALGORITHM, config.aes_key, iv); let encrypted = cipher.update(text); encrypted = Buffer.concat([encrypted, cipher.final()]); return iv.toString('hex') + ":" + encrypted.toString('hex'); }; - 封装解密函数
export const AESDecrypt = (text) => { if (!text || text.length === 0) return null; let textParts = text.split(':'); let iv = Buffer.from(textParts.shift(), 'hex'); let encryptedText = Buffer.from(textParts.join(':'), 'hex'); let decipher = createDecipheriv(AES_ALGORITHM, config.aes_key, iv); let decrypted = decipher.update(encryptedText); //TO_FIX: 下面这一行的 decipher.final() 会报错,注释掉就没事,但不知道不调用会有什么副作用... //decrypted = Buffer.concat([decrypted, decipher.final('utf8')]); return decrypted.toString(); }; - 需要在
config中配置aes_key
- 作用
-
RSA非对称加密-
作用1: 公钥加密,私钥解密
- 把公钥放出去,有人用公钥加密了内容传到服务器
- 只有拥有对应私钥,才能解密出真正的信息
-
作用2:私钥签名,公钥验证
- 用私钥来加密内容,分发给别人
- 别人手上有你的公钥,只有对应私钥签发的内容,才能被公钥解密
-
根目录下新建
cert目录mkdir certcd cert -
执行
openssl- 会出现
OpenSSL
- 会出现
-
生成私钥
genrsa -out common_rsa_private_key.pem 1024 -
根据私钥生成公钥
rsa -in common_rsa_private_key.pem -pubout -out common_rsa_public_key.pem -
封装加密函数(作用1)
export const RSAEncrypt = (s, public_key_path) => { if (!s || s.length === 0) return null; let publicKey = fs.readFileSync(public_key_path, 'ascii').toString(); let encryptResult = publicEncrypt({key: publicKey, padding: constants.RSA_PKCS1_PADDING}, Buffer.from(s,'utf8')) return encryptResult.toString('base64'); }; -
封装解密函数(作用1)
export const RSADecrypt = (s, private_key_path) => { if (!s || s.length === 0) return null; let privateKey = fs.readFileSync(private_key_path, 'ascii').toString(); let decryptResult = privateDecrypt({key: privateKey, padding: constants.RSA_PKCS1_PADDING}, Buffer.from(s,'base64')) return decryptResult.toString('utf8'); }; -
封装签名函数(作用2)
- 要用到
privateEncrypt
- 要用到
-
封装验签函数(作用2)
- 要用到
publicDecrypt
- 要用到
-
测试代码
const text = "test content for rsa encrypt" let encrypted = RSAEncrypt(text, __dirname + config.cert_common.public_key_path); console.log(encrypted); let dectypted = RSADecrypt(encrypted, __dirname + config.cert_common.private_key_path); console.log(dectypted)- 需要用到
import path from "path"; const __dirname = path.resolve();- 获取根目录
- 需要用到
-