欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

nodejs中各種加密算法的實(shí)現(xiàn)詳解

 更新時(shí)間:2019年07月11日 11:32:17   作者:小黎也  
這篇文章主要給大家介紹了關(guān)于nodejs中各種加密算法的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用nodejs具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

在大前端的趨勢(shì)下,前端er也要懂點(diǎn)數(shù)據(jù)加密相關(guān)的知識(shí)才行,加密算法的實(shí)現(xiàn)和原理我們可以不用深究,畢竟加密是一門(mén)高深的學(xué)科,但是基本的加密方式和編碼還是要掌握的,畢竟沒(méi)吃過(guò)豬肉,豬跑還是見(jiàn)過(guò)的嘛。

我對(duì)常見(jiàn)的幾種加密和簽名的算法做個(gè)歸納,同時(shí)附上 nodejs 的編碼實(shí)現(xiàn)。

加密算法

為了保證數(shù)據(jù)的安全性和防篡改,很多數(shù)據(jù)在傳輸中都進(jìn)行了加密。舉個(gè)場(chǎng)景的栗子,最近很多網(wǎng)站都升級(jí)到 https 協(xié)議, https 協(xié)議就是使用了非對(duì)稱加密和hash簽名,還有 github 使用的 ssh ,也是非對(duì)稱加密。還有大部分登錄時(shí)密碼采用的 MD5 加密等等。

加密可分為三大類(lèi),對(duì)稱加密和非對(duì)稱加密,還有摘要算法,我們一一展開(kāi)。

對(duì)稱加密

引用百科的描述:

采用單鑰密碼系統(tǒng)的加密方法,同一個(gè)密鑰可以同時(shí)用作信息的加密和解密,這種加密方法稱為對(duì)稱加密,也稱為單密鑰加密。

對(duì)稱加密很好理解,就好比我把我家的鑰匙給你,你要來(lái)我家,直接用這把鑰匙開(kāi)門(mén)就行。

對(duì)稱加密目前主流的有 AES 和 DES , AES 是新一代的標(biāo)準(zhǔn),速度快,安全級(jí)別更高。

AES

AES的加密模式有五種:CBC、ECB、CTR、OCF、CFB

  1. ECB:電子密本方式,需要一個(gè)密鑰即可,特點(diǎn)是簡(jiǎn)單,利于并行計(jì)算。
  2. CBC:密文分組鏈接方式,除了需要一個(gè)密鑰之外,還需要一個(gè)向量,向量的作用也是用于數(shù)據(jù)的加密,所以這個(gè)的安全性要好于 ECB
  3. CTR、OCF、CFB:具體算法的實(shí)現(xiàn)方式不一樣,優(yōu)缺點(diǎn)也各不相同,而這幾個(gè)都同 CBC 一樣,都需要密鑰和向量。

AES 有三種長(zhǎng)度 128位、192位、256位,這三種的區(qū)別,主要來(lái)自于密鑰的長(zhǎng)度,16字節(jié)密鑰=128位,24字節(jié)密鑰=192位,32字節(jié)密鑰=256位。如下表格:

長(zhǎng)度 密鑰長(zhǎng)度 向量長(zhǎng)度
128位 16 16
192位 24 16
256位 32 16

DES

加密默認(rèn)與 AES 相同,也有五種模式,除了 ECB 只需要密鑰,其他模式需要密鑰和向量。

與 AES 不同的是, DES 的密鑰長(zhǎng)度只有8字節(jié),向量也是8字節(jié)。

編碼實(shí)現(xiàn)

在 nodejs 中的實(shí)現(xiàn)

/**
 * @description 
 * 對(duì)稱加密
 * @param {*} data 加密數(shù)據(jù)
 * @param {*} algorithm 加密算法
 * @param {*} key 密鑰
 * @param {*} iv 向量
 * @returns
 */
function cipherivEncrypt(data, algorithm, key, iv) {
 const cipheriv = crypto.createCipheriv(algorithm, key, iv)
 let encrypted = cipheriv.update(data, 'utf8', 'hex');
 encrypted += cipheriv.final('hex');
 return encrypted
}

/**
 * @description
 * 對(duì)稱解密
 * @param {*} data 解密數(shù)據(jù)
 * @param {*} algorithm 解密算法
 * @param {*} key 密鑰
 * @param {*} iv 向量
 * @returns
 */
function cipherivDecrypt(data, algorithm, key, iv) {
 const decipher = crypto.createDecipheriv(algorithm, key, iv);
 let decrypted = decipher.update(data, 'hex', 'utf8');
 decrypted += decipher.final('utf8');
 return decrypted
}

使用官方提供 crypto 庫(kù)來(lái)實(shí)現(xiàn)加解密,上面的代碼中加密后輸出的是 16 進(jìn)制的字符串,大家可以根據(jù)具體情況換成其他格式的數(shù)據(jù)。

調(diào)用方式如下

// AES對(duì)稱加解密
const str = 'xiaoliye';
const key = 'aaaaaaaaaaaaaaaaaaaaaaaa'; // 24
const iv = 'aaaaaaaaaaaaaaaaaaaaaaaa'; // 24
const cipherAesText = cipherivEncrypt(str, 'aes-192-cfb', key,iv)
const resultText = cipherivDecrypt(cipherAesText, 'aes-192-cfb', key,iv)
console.log(resultText === str) // true
// DES對(duì)稱加解密
const str = 'xiaoliye';
const key = 'aaaaaaaa'; //8
const iv = 'aaaaaaaa'; //8
const cipherAesText = cipherivEncrypt(str, 'des-cfb', key,iv)
const resultText = cipherivDecrypt(cipherAesText, 'des-cfb', key,iv)
console.log(resultText === str) / true

非對(duì)稱加密

非對(duì)稱加密,有兩把鑰匙,公鑰和私鑰,如下圖:

公鑰是可以公開(kāi)對(duì)外,私鑰就是自個(gè)的,不可泄露。因?yàn)橛袃蓚€(gè)密鑰,非對(duì)稱加密這個(gè)名字就是這么由來(lái)的。

發(fā)送方用接收方公開(kāi)對(duì)外的公鑰進(jìn)行加密,接收方收到數(shù)據(jù)后,用私鑰進(jìn)行解密,業(yè)務(wù)處理完后,用私鑰給需要回傳的數(shù)據(jù)加密,收到數(shù)據(jù)的一方在用公鑰解密。

這個(gè)過(guò)程就是非對(duì)稱加解密,簡(jiǎn)單理解就是公鑰加密的數(shù)據(jù),用私鑰解密;私鑰加密的數(shù)據(jù),用公鑰解密。

非對(duì)稱加密與對(duì)稱加密相比,安全性要高很多。對(duì)于對(duì)稱加密,密鑰鑰匙被某一方不小心泄露了,那秘文就有可能被破解和篡改。而非對(duì)稱加密,公鑰隨意流通,只要頒發(fā)密鑰的一方好好把私鑰保管好,安全性是妥妥的。

編碼實(shí)現(xiàn)

我們來(lái)看 node 中的編碼實(shí)現(xiàn),還是使用官方提供的 crypto 庫(kù)

  • 加解密函數(shù)接收的數(shù)據(jù)是 Buffer 類(lèi)型,(關(guān)于 Buffer 的介紹,不了解的朋友可以看下這篇二進(jìn)制與Buffer),所以需要約定好接收和輸出的數(shù)據(jù)類(lèi)型。
  • 參數(shù) padding 是填充方式,有這么幾種 crypto.constants.RSA_NO_PADDING, crypto.constants.RSA_PKCS1_PADDING, crypto.constants.RSA_PKCS1_OAEP_PADDING,因?yàn)闆](méi)有深入研究過(guò),就不展開(kāi)啦,不過(guò)有一點(diǎn),加密和解密的填充方式必須是要一致的。
const constants = require('constants')
const crypto = require('crypto')

/**
 * @description
 * 公鑰加密數(shù)據(jù)
 * @param {*} data 待加密數(shù)據(jù)
 * @param {*} publicKey 公鑰
 * @param {*} inputEncoding 加密數(shù)據(jù)類(lèi)型
 * @param {*} outputEncoding 輸出的數(shù)據(jù)類(lèi)型
 * @param {*} padding 填充方式
 * @returns
 */
function publicEncrypt(data, publicKey, inputEncoding, outputEncoding, padding) {
 const encryptText = crypto.publicEncrypt({
  key: publicKey,
  padding: padding || constants.RSA_PKCS1_PADDING
 }, Buffer.from(data, inputEncoding));

 return encryptText.toString(outputEncoding);
}

/**
 * @description
 * 公鑰解密數(shù)據(jù)
 * @param {*} data 待解密數(shù)據(jù)
 * @param {*} publicKey 公鑰
 * @param {*} inputEncoding 解密數(shù)據(jù)類(lèi)型
 * @param {*} outputEncoding 輸出的數(shù)據(jù)類(lèi)型
 * @param {*} padding 填充方式
 * @returns
 */
function publicDecrypt(data, publicKey, inputEncoding, outputEncoding, padding) {
 let decryptText = '';
 const decryptText = crypto.publicDecrypt({
  key: publicKey,
  padding: padding || constants.RSA_PKCS1_PADDING
 }, Buffer.from(data, inputEncoding));

 return decryptText.toString(outputEncoding);
}

/**
 * @description
 * 私鑰加密數(shù)據(jù)
 * @param {*} data 待加密數(shù)據(jù)
 * @param {*} privateKey 私鑰
 * @param {*} inputEncoding 加密數(shù)據(jù)類(lèi)型
 * @param {*} outputEncoding 輸出的數(shù)據(jù)類(lèi)型
 * @param {*} padding 填充方式
 * @returns
 */
function privateEncrypt(data, privateKey, inputEncoding, outputEncoding, padding) {
 const encryptText = crypto.privateEncrypt({
  key: privateKey,
  padding: padding || constants.RSA_PKCS1_PADDING
 }, Buffer.from(data, inputEncoding));

 return encryptText.toString(outputEncoding);
}

/**
 * @description
 * 私鑰解密數(shù)據(jù)
 * @param {*} data 待解密數(shù)據(jù)
 * @param {*} privateKey 私鑰
 * @param {*} inputEncoding 解密數(shù)據(jù)類(lèi)型
 * @param {*} outputEncoding 輸出的數(shù)據(jù)類(lèi)型
 * @param {*} padding 填充方式
 * @returns
 */
function privateDecrypt(data, privateKey, inputEncoding, outputEncoding, padding) {
 const decryptText = crypto.privateDecrypt({
  key: privateKey,
  padding: padding || constants.RSA_PKCS1_PADDING
 }, Buffer.from(data, inputEncoding));
 return decryptText.toString(outputEncoding);
}

有四個(gè)函數(shù),分別是公鑰的加解密和私鑰的加解密,我們看下如何使用,示例中是我自己生成的密鑰對(duì),大家可以自行替換

const rsaPublicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCncWDMXEToSxtGQCmWY2ywl5CQ
tb81PXYZch4v5M8MNUZPpcmf+VDXQbuWqqTqV/tY7rLviu/BAkFbX9NiFCapF5lP
siVwSGWJQwq0S/++RCwB6yFVEzOKL25jANRBVNwmSOzojveCStYPcEs5Q829ld68
9TzluDDqUS69dTHGkQIDAQAB
-----END PUBLIC KEY-----`

const rsaPrivateKey = `-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKdxYMxcROhLG0ZA
KZZjbLCXkJC1vzU9dhlyHi/kzww1Rk+lyZ/5UNdBu5aqpOpX+1jusu+K78ECQVtf
02IUJqkXmU+yJXBIZYlDCrRL/75ELAHrIVUTM4ovbmMA1EFU3CZI7OiO94JK1g9w
SzlDzb2V3rz1POW4MOpRLr11McaRAgMBAAECgYEAhNa8/cQh4sxbKgOTOr1MKFlG
Fpgpxroo7I0Nh9+Vp1DIpD2Z1PF9ghijEyf0R/pe7LIKgWIPTWdVpIFEeSYVeH43
FLr3zwR9oXzwG7RQTSN4d/Xcvg+24ZxCrvDfn7qDIlXh0jOS0wCvna1or7xgPcOu
XG8J3BNbBdUixM0lk0ECQQDR4SCelWn0BY21jsFobX+pGqKOsj+tuvU4Cz47Gmev
qvq2suYXwLemkP7EqRu8iNso/IzvrdsuJDG76dzwC4D5AkEAzDz2cDrKOVmqYw7s
luOQFHl1TzmY7Umpd9YbZ5iXn0eCjIn1/e1risRF5+IeSpB84OVltUzj4cVDCbFd
9S1wWQJAIeKcFp5+9cPzxi1fMpIDO3Uua6WBvHXj44GFMZuow+byBY9KsOkPfZgJ
Wg0Hil/6KlrkEkpaic+ULAetASCKWQJAdMh/Gdlj/LsaxJ2qBvWEU1DIFU8X9Mbk
ElPpQ6lrOXaIXZgdgt8ZWTW1y0vuijBoV6iUKcEXpOdI1+gFk8YxsQJBAJsGJClf
E1mE6CZgegM82428g4osZznVXBO/QtrQsA78S1xo8bo4qwVm0jQBcto65gwlfeeB
Xm7MiIvNVBqzTVs=
-----END PRIVATE KEY-----
`

const str = 'xiaoliye'
const cipherText = publicEncrypt(str, rsaPublicKey, 'utf8', 'hex') // 公鑰加密
const decryptText = privateDecrypt(cipherText, rsaPrivateKey, 'hex', 'utf8') // 私鑰解密
console.log(str === decryptText) // true

const cipherTextPrivate = privateEncrypt(str,rsaPrivateKey,'utf8', 'hex') // 私鑰加密
const decryptTextPublic = publicDecrypt(cipherTextPrivate,rsaPublicKey, 'hex', 'utf8') // 公鑰解密
console.log(str === decryptTextPublic) // true

密鑰生成方式

網(wǎng)上有很多工具可以一鍵生成配對(duì)的公鑰和私鑰,淘寶、微信都有提供相關(guān)工具,或者使用 OpenSSL 生成也可以。

摘要算法(HASH)

把任意長(zhǎng)度的輸入,根據(jù)算法生成一串固定長(zhǎng)度的偽隨機(jī)數(shù),這一算法就是摘要算法,它有這么幾個(gè)特點(diǎn)

  1. 不需要密鑰,加密出來(lái)的數(shù)據(jù)無(wú)法被解密,具有不可逆性。
  2. 生成的摘要長(zhǎng)度是固定的,與輸入無(wú)關(guān)。
  3. 相同的輸入,使用相同的實(shí)現(xiàn),生成的摘要一定相同;不同的輸入,生成的摘要是大相徑庭的,即,不會(huì)發(fā)生碰撞。

根據(jù)這些特點(diǎn),摘要算法通常用于生成簽名,用來(lái)驗(yàn)證數(shù)據(jù)的完整性。

還有用戶密碼的存儲(chǔ),如今密碼的存儲(chǔ)主流的方式,就是使用摘要算法生成唯一的標(biāo)識(shí),為了保證安全性,通常在生成摘要后再加上一串隨機(jī)數(shù)(加鹽salt),在來(lái)hash一次。

目前主流的實(shí)現(xiàn)有 MD5 和 SHA-2 , MD5 生成的摘要是 32 字節(jié), sha256 生成的摘要是 64 字節(jié)。

編碼實(shí)現(xiàn)

仍然是使用官方提供的 crypto 庫(kù)

/**
 * @description
 * md5
 * @param {*} data
 * @returns
 */
function md5(data){
 const hash = crypto.createHash('md5');
 return hash.update(data).digest('hex');
}

/**
 * @description
 * sha256
 * @param {*} data
 * @returns
 */
function sha256(data){
 const hash = crypto.createHash('sha256');
 return hash.update(data).digest('hex');
}

console.log(md5('asdf')) // 912ec803b2ce49e4a541068d495ab570
console.log(sha256('asdf')) // f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b

小結(jié)

涉及加密的活一般是后臺(tái)開(kāi)發(fā)干的,但前端靚仔懂點(diǎn)加密,會(huì)讓自己酷酷的~

小伙伴們還有遇到啥其他加密的方式,歡迎一起交流啊~

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • node puppeteer(headless chrome)實(shí)現(xiàn)網(wǎng)站登錄

    node puppeteer(headless chrome)實(shí)現(xiàn)網(wǎng)站登錄

    這篇文章主要介紹了node puppeteer(headless chrome)實(shí)現(xiàn)網(wǎng)站登錄,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 前端如何更好的展示后端返回的十萬(wàn)條數(shù)據(jù)

    前端如何更好的展示后端返回的十萬(wàn)條數(shù)據(jù)

    這篇文章主要為大家介紹了前端如何更好的展示后端返回的十萬(wàn)條數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • 深入理解Puppeteer的入門(mén)教程和實(shí)踐

    深入理解Puppeteer的入門(mén)教程和實(shí)踐

    這篇文章主要介紹了深入理解Puppeteer的入門(mén)教程和實(shí)踐,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • 在Node.js中實(shí)現(xiàn)獲取用戶頻道信息的功能

    在Node.js中實(shí)現(xiàn)獲取用戶頻道信息的功能

    在構(gòu)建社交或視頻分享平臺(tái)時(shí),允許用戶查看其他用戶的頻道信息是一個(gè)基本需求,本文將介紹如何在Node.js應(yīng)用中,使用Express框架和Mongoose庫(kù)來(lái)實(shí)現(xiàn)這一功能,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-04-04
  • Nodejs實(shí)現(xiàn)的操作MongoDB數(shù)據(jù)庫(kù)功能完整示例

    Nodejs實(shí)現(xiàn)的操作MongoDB數(shù)據(jù)庫(kù)功能完整示例

    這篇文章主要介紹了Nodejs實(shí)現(xiàn)的操作MongoDB數(shù)據(jù)庫(kù)功能,結(jié)合完整實(shí)例形式分析了nodejs針對(duì)MongoDB數(shù)據(jù)庫(kù)的連接及增刪改查基本操作技巧,需要的朋友可以參考下
    2019-02-02
  • 使用Node.js實(shí)現(xiàn)獲取視頻詳情

    使用Node.js實(shí)現(xiàn)獲取視頻詳情

    這篇文章主要為大家詳細(xì)介紹了如何在Node.js應(yīng)用程序中實(shí)現(xiàn)獲取視頻詳情的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • node.js中實(shí)現(xiàn)GET和POST請(qǐng)求的代碼示例

    node.js中實(shí)現(xiàn)GET和POST請(qǐng)求的代碼示例

    在很多場(chǎng)景中,我們的服務(wù)器都需要跟用戶的瀏覽器打交道,如發(fā)送驗(yàn)證碼、登錄表單提交,請(qǐng)求服務(wù)器數(shù)據(jù)一般都使用GET請(qǐng)求,表單提交到服務(wù)器一般都使用POST請(qǐng)求,本文詳細(xì)介紹了在Node.js中如何處理GET和POST請(qǐng)求,需要的朋友可以參考下
    2024-12-12
  • nodejs簡(jiǎn)單抓包工具使用詳解

    nodejs簡(jiǎn)單抓包工具使用詳解

    這篇文章主要介紹了nodejs簡(jiǎn)單抓包工具使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Windows下Node爬蟲(chóng)神器Puppeteer安裝記

    Windows下Node爬蟲(chóng)神器Puppeteer安裝記

    這篇文章主要介紹了Windows下Node爬蟲(chóng)神器Puppeteer安裝記,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Yapi安裝部署詳細(xì)圖文教程

    Yapi安裝部署詳細(xì)圖文教程

    YApi 是一個(gè)可本地部署的、打通前后端及QA的、可視化的接口管理平臺(tái),下面這篇文章主要給大家介紹了關(guān)于Yapi安裝部署的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09

最新評(píng)論