前端如何用密文跟後端互通?原來那麼簡單!
後端: 這次不行哇,新來的測試不好糊弄呢!必須要國密 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);
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 時,也需要注意遵循最佳的安全實踐,確保密鑰的安全存儲和管理,以防止潛在的安全風險。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/V6potIm2ildxf-rVuhTcuA