前端如何用密文跟后端互通?原来那么简单!

大厂技术  高级前端  Node进阶
点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群

文章来源于稀土掘金技术社区——大码猴

后端:密码得走密文哇!

我: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()); // 输出原始消息
d3128351b59d1d5c9d763ddfeef10dd2.jpeg
image.png

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);
7a24dc3a9bbc84349adc5ae78a3d9ef3.jpeg
image.png

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()); // 输出原始消息
56aa0d7e34f2ed9581ad690ed0f9c742.jpeg
image.png

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);

0e1d28e63da8624b23e3fbd0c51471a4.jpeg验签(Verify Signature)

const message = '这是要验证签名的消息'; // 应与签名时使用的消息相同  
const sigValueHex = '签名值'; // 替换为实际的签名值字符串,即签名步骤中生成的sigValueHex  
  
// 使用公钥验证签名是否有效  
let verifyResult = sm2.doVerifySignature(message, sigValueHex, publicKey);  
  
console.log('验签结果:', verifyResult); // 如果验证成功,应输出true;否则输出false
c0c6aa28de8d463989cc8a0e57c99d42.jpeg
image.png

实战例子

登录注册,对用户密码进行加密

注意:前端是不储存任何涉及安全的密钥(公钥是直接拿后端生成的)。

新建个工具文件,专门存放加密逻辑,我这用的是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时,也需要注意遵循最佳的安全实践,确保密钥的安全存储和管理,以防止潜在的安全风险。

Node 社群

 
 

我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。

3962c890ad97fdbcc1e3f59405083269.png

“分享、点赞、在看” 支持一下
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值