sm2加密与解密

受朋友的委托,需要做一个密码键盘,其中需要用到国密sm2来进行前后端数据的通信,琢磨了一整天,特此记录,以便之后来查阅~

1.工具库

       (1) jquery-3.6.0.min.js  

       (2) jsencrypt.min.js

 <script src="https://cdn.jsdelivr.net/npm/jsencrypt@3.2.1/bin/jsencrypt.min.js"></script>

        (3) node-rsa  (npm包)

2.交互逻辑

        大概就是后端生成公钥和私钥,之后将公钥传递给前端,前端拿到公钥对数据进行加密,之后传递加密过的数据到后端,后端使用私钥进行解密,整个数据传输过程原数据全程不会暴露,简直安全的一批!

3.实现

      (1)  先把后端搭建起来

需要用到的库

koa,  node框架
koa-router,  路由
koa-cors,   解决跨域
koa-bodyparser ,  解析传递参数

const koa = require("koa");
const router = require("koa-router")();
const cors = require("koa-cors");
const bodyparser = require("koa-bodyparser");
const {doDecryptStr,publicKey } = require("./excode");

let app = new koa();
router.post("/login", async (ctx, next) => {
  let { value } = ctx.request.body;
  let res =  doDecryptStr(value);
  console.log("加密的数据"+value);
  console.log("解密后的数据"+res);
  ctx.body = {
    code: 1000,
    msg: res,
  };
});
router.post("/", async (ctx, next) => {
    ctx.body = {
      code: 200,
      msg: publicKey,
    };
  });
app.use(cors());
app.use(bodyparser());
app.use(router.routes());

let port = 1228;
app.listen(port);
console.log(`本次服务器将运行在:http://localhost:${port}`);

之后生成公钥和私钥

依赖:node-rsa

const NodeRSA = require("node-rsa");
const key = new NodeRSA({b: 512});//生成512位秘钥
const publicKey = key.exportKey('pkcs8-public');//导出公钥
const _prikey = key.exportKey('pkcs8-private');//导出私钥
function doDecryptStr(baseStr) {
  const privateKey = new NodeRSA(_prikey);
  privateKey.setOptions({ encryptionScheme: "pkcs1" }); // 因为jsencrypt自身使用的是pkcs1加密方案, nodejs需要修改成pkcs1。
  decrypted = privateKey.decrypt(baseStr, "utf8");
  return decrypted;
}

module.exports = {
  publicKey,
  doDecryptStr,
};

        (2)前端部分逻辑

刚打开页面需要拿到后端生成的公钥,所以...

 _pubKey  :用来存放公钥的变量

  var _pubKey;
      $.post("http://localhost:1228/", (res) => {
          console.log(res);
          _pubKey = res.msg;
        });

输入完成点击登录时...

将加密的数据传递至后端,之后就交给后端来解密了~

 let login = () => {
        var encrypt = new JSEncrypt();
        encrypt.setPublicKey(_pubKey);
        var res = encrypt.encrypt(pswd.value);
        $.post("http://localhost:1228/login", { value: res }, (res) => {
          console.log(res);
        });
        btn.style.opacity = "0%";
        key.style.bottom = "-270px";
      };

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下步骤来实现 JavaScript 中的 SM2 加密和 Java 中的解密: JavaScript 中的 SM2 加密: 1. 使用 SM2 加密算法库(例如 jsrsasign)生成公私钥对。 2. 使用公钥加密明文数据。 3. 将加密后的数据转换为 Base64 编码格式。 4. 将加密后的数据发送给后端。 以下是 JavaScript 中使用 jsrsasign 库进行 SM2 加密的示例代码: ```javascript // 生成公私钥对 var keypair = KEYUTIL.generateKeypair("SM2"); // 获取公钥 var publicKey = keypair.pubKeyObj; // 加密明文数据 var plainText = "Hello World"; var encryptedData = publicKey.encrypt(plainText); // 将加密后的数据转换为 Base64 编码格式 var base64Data = hextob64(encryptedData); // 发送加密后的数据给后端 sendDataToServer(base64Data); ``` Java 中的 SM2 解密: 1. 使用 SM2 加密算法库(例如 bcprov-jdk15on)读取私钥。 2. 将从前端接收到的 Base64 编码格式的数据转换为 byte 数组。 3. 使用私钥解密数据。 以下是 Java 中使用 bcprov-jdk15on 库进行 SM2 解密的示例代码: ```java // 读取私钥 PEMParser pemParser = new PEMParser(new FileReader("private_key.pem")); JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); Object object = pemParser.readObject(); PEMKeyPair pemKeyPair = (PEMKeyPair) object; PrivateKey privateKey = converter.getPrivateKey(pemKeyPair.getPrivateKeyInfo()); // 将从前端接收到的 Base64 编码格式的数据转换为 byte 数组 byte[] base64Data = Base64.getDecoder().decode(data); // 使用私钥解密数据 SM2Engine sm2Engine = new SM2Engine(); sm2Engine.init(false, new ParametersWithRandom(new SM2PrivateKeyParameters(privateKey, new SM2Parameters()))); byte[] decryptedData = sm2Engine.processBlock(base64Data, 0, base64Data.length); String plainText = new String(decryptedData, "UTF-8"); ``` 需要注意的是,JavaScript 中的 SM2 加密库和 Java 中的 SM2 解密库必须使用相同的参数配置,例如密钥长度、填充方式等。另外,为了保证数据的安全性,建议在传输过程中使用 HTTPS 协议加密数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值