Nest.js散列與加密實(shí)例詳解
0x0 前言
先要知道,什么是散列算法呢?產(chǎn)生一些數(shù)據(jù)片段(例如消息或會話項(xiàng))的散列值的算法。例如,md5就是一種散列算法。軟件開發(fā)中的散列函數(shù)或散列算法,又稱哈希函數(shù),英語:Hash Function,是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。所有散列函數(shù)都有如下一個(gè)基本特性:如果兩個(gè)散列值是不相同的(根據(jù)同一函數(shù)),那么這兩個(gè)散列值的原始輸入也是不相同的。
加 密算法通常分為對稱性加密算法和非對稱性加密算法,對于對稱性加密算法,信息接收雙方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是對數(shù)據(jù)進(jìn)行 加解密了。非對稱算法與之不同,發(fā)送雙方A,B事先均生成一堆密匙,然后A將自己的公有密匙發(fā)送給B,B將自己的公有密匙發(fā)送給A,如果A要給B發(fā)送消 息,則先需要用B的公有密匙進(jìn)行消息加密,然后發(fā)送給B端,此時(shí)B端再用自己的私有密匙進(jìn)行消息解密,B向A發(fā)送消息時(shí)為同樣的道理。
散列和加密本質(zhì)上都是將一個(gè)Object變成一串無意義的字符串,不同點(diǎn)是經(jīng)過散列的對象無法復(fù)原,是一個(gè)單向的過程。例如,對密碼的加密通常就是使用散列算法,因此用戶如果忘記密碼只能通過修改而無法獲取原始密碼。但是對于信息的加密則是正規(guī)的加密算法,經(jīng)過加密的信息是可以通過秘鑰解密和還原。
散列與加密
散列是給鍵值經(jīng)過數(shù)學(xué)算法轉(zhuǎn)換另外一個(gè)鍵值,在轉(zhuǎn)換過程中是利用哈希函數(shù)生成,輸出的內(nèi)容無法還原,這邊主要用于密碼存儲在數(shù)據(jù)需要進(jìn)行散列處理。
加密是對信息編碼,將原始信息轉(zhuǎn)換成密文,一般用于客戶端向服務(wù)器發(fā)送密碼等敏感信息,發(fā)送之前對此信息加密,然后在服務(wù)器再進(jìn)行解密。
0x1 散列
Node.js 生態(tài)有很多依賴,例如Bcrypt 和 Argon2 ,本身使用起來很簡單,這次使用 Bcrypt 來實(shí)現(xiàn)散列過程:
yarn add bcrypt yarn add @types/bcrypt -D
然后對散列的業(yè)務(wù)進(jìn)行封裝:
import { Injectable } from '@nestjs/common' import * as bcrypt from 'bcrypt' @Injectable() export class BcryptService { private static readonly SALT_ROUNDS: number = 10 /** * 對比檢查密碼 * @param rawStr * @param hashedStr */ async compare(rawStr: string, hashedStr: string) { return bcrypt.compare(rawStr, hashedStr) } /** * 生成 hash * @param rawStr * @param salt */ async hash(rawStr: string, salt?: string) { return bcrypt.hash(rawStr, salt || BcryptService.SALT_ROUNDS) } /** * 生成鹽 */ async genSalt() { return bcrypt.genSalt(BcryptService.SALT_ROUNDS) } }
0x2 加密
Node.js 系統(tǒng)內(nèi)自帶 加密模塊 ,可用于加密和解密等相關(guān)操作,下面進(jìn)行使用 AES-256-CTR 加密方式對數(shù)據(jù)進(jìn)行加密:
import { createCipheriv, randomBytes } from 'crypto' import { promisify } from 'util' const iv = randomBytes(16) const password = 'Password used to generate key' // 密鑰長度取決于算法 // 在 aes256 情況下是 32 個(gè)字節(jié)長度 const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer const cipher = createCipheriv('aes-256-ctr', key, iv) const textToEncrypt = 'Nest' const encryptedText = Buffer.concat([ cipher.update(textToEncrypt), cipher.final() ])
如果需要解密也很簡單:
import { createDecipheriv } from 'crypto' const decipher = createDecipheriv('aes-256-ctr', key, iv) const decryptedText = Buffer.concat([ decipher.update(encryptedText), decipher.final() ])
0x3 參考
總結(jié)
到此這篇關(guān)于Nest.js散列與加密的文章就介紹到這了,更多相關(guān)Nest.js散列與加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Node.js實(shí)現(xiàn)一個(gè)簡單的FastCGI服務(wù)器實(shí)例
這篇文章主要介紹了使用Node.js實(shí)現(xiàn)一個(gè)簡單的FastCGI服務(wù)器實(shí)例,也可以作為一個(gè)比較詳細(xì)的Node.js服務(wù)器創(chuàng)建教程,需要的朋友可以參考下2014-06-06基于NodeJS+MongoDB+AngularJS+Bootstrap開發(fā)書店案例分析
這章的目的是為了把前面所學(xué)習(xí)的內(nèi)容整合一下,這個(gè)示例完成一個(gè)簡單圖書管理模塊,因?yàn)橹虚g需要使用到Bootstrap這里先介紹Bootstrap2017-01-01Node.js重新刷新session過期時(shí)間的方法
在Node.js中,我們通常使用express-session這個(gè)包來使用和管理session,保存服務(wù)端和客戶端瀏覽器之間的會話狀態(tài)。那如何才能實(shí)現(xiàn)當(dāng)用戶刷新當(dāng)前頁面或者點(diǎn)擊頁面上的按鈕時(shí)重新刷新session的過期時(shí)間呢,接下來通過本文一起學(xué)習(xí)吧2016-02-02Node.js中的Buffer對象及創(chuàng)建方式
node.js提供了一個(gè)Buffer對象來提供對二進(jìn)制數(shù)據(jù)的操作,Buffer?類的實(shí)例類似于整數(shù)數(shù)組,但?Buffer?的大小是固定的、且在?V8?堆外分配物理內(nèi)存。本文給大家介紹Node.js中的Buffer對象及創(chuàng)建方式,感興趣的朋友一起看看吧2022-01-01從零開始學(xué)習(xí)Node.js系列教程四:多頁面實(shí)現(xiàn)數(shù)學(xué)運(yùn)算的client端和server端示例
這篇文章主要介紹了Node.js多頁面實(shí)現(xiàn)數(shù)學(xué)運(yùn)算的client端和server端,結(jié)合具體實(shí)例形式分析了nodejs客戶端提交與服務(wù)端處理實(shí)現(xiàn)數(shù)學(xué)運(yùn)算的相關(guān)操作技巧,需要的朋友可以參考下2017-04-04Node.js實(shí)現(xiàn)下載文件的兩種實(shí)用方式
最近優(yōu)化了幾個(gè)新人寫出的動態(tài)表格文件下載接口的性能瓶頸,感覺非常有必要總結(jié)一篇文章作為文檔來拋磚引玉,這篇文章主要給大家介紹了關(guān)于Node.js實(shí)現(xiàn)下載文件的兩種實(shí)用方式,需要的朋友可以參考下2022-09-09