🧑💻 寫在開頭
點贊 + 收藏 === 學會🤣🤣🤣
後端:密碼得走密文哇!
我:base64?md5?
後端:這次不行哇,新來的測試不好糊弄呢!必須要國密sm2加密捏
我: 好吧,看我的。
我這邊使用的是sm-crypto
,當然也有很多優秀的庫如:forge
,我在業務上搭配jszip做過上傳zip檔案內藏加密後的私鑰進行證書登入,還是不錯的支援,但是文件社群不是很友好,所以推薦sm-crypto
,接下來讓我們一起使用它吧。
sm-crypto
是一個基於Node.js的密碼學庫,專為與國密演算法(中國密碼演算法標準)相容而設計。它提供了各種加密、解密、簽名和驗證功能。
sm-crypto
包含多種密碼演算法的實現,例如:
- SM1:對稱加密演算法,其加密強度與AES相當,但該演算法不公開,呼叫時需要透過加密晶片的介面進行呼叫。
- SM2:非對稱加密演算法,基於ECC(橢圓曲線密碼學)。該演算法已公開,且由於基於ECC,其簽名速度與秘鑰生成速度都快於RSA。此外,ECC 256位(SM2採用的就是ECC 256位的一種)的安全強度比RSA 2048位高,但運算速度快於RSA。
- SM3:訊息摘要演算法,可以用MD5作為對比理解,其校驗結果為256位。
- SM4:無線區域網標準的分組資料演算法,屬於對稱加密,金鑰長度和分組長度均為128位。
sm-crypto內部方法介紹
1.SM2加密與解密
SM2是一種基於橢圓曲線密碼學的非對稱加密演算法。sm-crypto提供了SM2的金鑰生成、加密、解密等功能。透過呼叫相關方法,開發者可以輕鬆地生成SM2金鑰對,並使用公鑰進行加密、私鑰進行解密。
const { sm2 } = require('sm-crypto'); const keyPair = sm2.generateKeyPairHex(); // 生成金鑰對 const publicKey = keyPair.publicKey; // 公鑰 const privateKey = keyPair.privateKey; // 私鑰 const message = 'Hello, SM2!'; // 待加密的訊息 const encrypted = sm2.doEncrypt(message, publicKey, { hash: true }); // 使用公鑰加密 const decrypted = sm2.doDecrypt(encrypted, privateKey, { hash: true, raw: true }); // 使用私鑰解密 console.log('加密結果:', encrypted); console.log('解密結果:', decrypted.toString()); // 輸出原始訊息
2.SM3摘要演算法
SM3是一種密碼雜湊演算法,用於生成訊息的摘要值。sm-crypto提供了SM3的摘要計算功能,開發者可以透過呼叫相關方法計算任意訊息的SM3摘要值。
const { sm3 } = require('sm-crypto'); const message = 'Hello, SM3!'; // 待計算摘要的訊息 const digest = sm3(message); // 計算SM3摘要值 console.log('SM3摘要值:', digest);
3.SM4分組加密演算法
SM4是一種分組密碼演算法,適用於無線區域網等場景。sm-crypto提供了SM4的加密與解密功能,開發者可以使用SM4金鑰對資料進行加密和解密操作。
const sm4 = require('sm-crypto').sm4; | const sm4 = require('sm-crypto').sm4; const key = '0123456789abcdeffedcba9876543210'; // 16位元組的SM4金鑰 const message = 'Hello, SM4!'; // 待加密的訊息 const encrypted = sm4.encrypt(Buffer.from(message), Buffer.from(key, 'hex')); // 加密 const decrypted = sm4.decrypt(encrypted, Buffer.from(key, 'hex')); // 解密 console.log('加密結果:', encrypted.toString('hex')); console.log('解密結果:', decrypted.toString()); // 輸出原始訊息
4、簽名/驗籤
簽名(Sign)
const { sm2 } = require('sm-crypto'); const keyPair = sm2.generateKeyPairHex(); // 生成金鑰對 const publicKey = keyPair.publicKey; // 公鑰 const privateKey = keyPair.privateKey; // 私鑰 const message = '這是要簽名的訊息'; // 替換為實際要簽名的訊息 // 使用私鑰對訊息進行簽名 let sigValueHex = sm2.doSignature(message, privateKey); console.log('簽名結果:', sigValueHex);
驗籤(Verify Signature)
const message = '這是要驗證簽名的訊息'; // 應與簽名時使用的訊息相同 const sigValueHex = '簽名值'; // 替換為實際的簽名值字串,即簽名步驟中生成的sigValueHex // 使用公鑰驗證簽名是否有效 let verifyResult = sm2.doVerifySignature(message, sigValueHex, publicKey); console.log('驗簽結果:', verifyResult); // 如果驗證成功,應輸出true;否則輸出false
實戰例子
登入註冊,對使用者密碼進行加密
注意:前端是不儲存任何涉及安全的金鑰(公鑰是直接拿後端生成的)。
新建個工具檔案,專門存放加密邏輯,我這用的是SM2
// smCrypto.js import { sm2 } from 'sm-crypto' // 引入加密庫 export const doEncrypt = ( // 加密 data, pKey = publicKey, cipherMode = 0 ) => sm2.doEncrypt( typeof data === 'object' ? JSON.stringify(data) : data, pKey, cipherMode ) export const encryptionPwd = async data => { // 加密密碼高階 let servePublicKey = '' await user.getSm2Pkeys() .then(res => { servePublicKey = res.data.content }) return doEncrypt( data, servePublicKey ) }
sm-crypto
作為一款基於Node.js的國密演算法庫,為開發者提供了豐富的密碼學功能。透過呼叫sm-crypto的內部方法,開發者可以輕鬆地實現SM2加密與解密、SM3摘要計算以及SM4分組加密等操作。這些功能在保障資料安全、構建安全應用等方面發揮著重要作用。同時,開發者在使用sm-crypto時,也需要注意遵循最佳的安全實踐,確保金鑰的安全儲存和管理,以防止潛在的安全風險。如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。