从零玩转前后端加解密之SM2-sm2

title: 从零玩转前后端加解密之SM2
date: 2022-08-21 19:42:00.907
updated: 2023-03-30 13:28:48.866
url: https://www.yby6.com/archives/sm2
categories: 
- 加密算法
- 从零玩转系列
tags: 
- 加密算法
- sm2

前言

SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法。

SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换RSA算法。

随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。

SM2算法和RSA算法比较

SM2性能更优更安全:密码复杂度高、处理速度快、机器性能消耗更小
详细参考: https://www.ecaa.org.cn/667.html

SM2RSA
算法结构基本椭圆曲线(ECC)基于特殊的可逆模幂运算
计算复杂度完全指数级亚指数级
存储空间192-256bit2048-4096bit
秘钥生成速度较RSA算法快百倍以上
解密加密速度较快一般
加密长度限制117

后端代码实现

添加 sm2 依赖

<dependency>
    <groupId>com.antherd</groupId>
    <artifactId>sm-crypto</artifactId>
    <version>0.3.2</version>
</dependency>

获取密钥对

@org.junit.Test
    public void generateKeyPairHex (){
      // 生成出来的密钥可无缝衔接 前端 js 加解密
        Keypair keypair = Sm2.generateKeyPairHex();
        String privateKey = keypair.getPrivateKey(); // 公钥
        String publicKey = keypair.getPublicKey(); // 私钥

        System.out.println(privateKey);
        System.out.println(publicKey);

        System.out.println("========================");
}

 @org.junit.Test
    public void t2 () {
        Keypair keypair = Sm2.generateKeyPairHex();
        String privateKey = keypair.getPrivateKey(); // 公钥
        String publicKey = keypair.getPublicKey(); // 私钥
        System.out.println(privateKey);
        System.out.println(publicKey);
        System.out.println("========================");
        // cipherMode 1 - C1C3C2,0 - C1C2C3,默认为1
        // 使用公钥加密
        final String doEncrypt = Sm2.doEncrypt("https://yby6.com,https://yangbuyi.top", publicKey);
        System.out.println("加密: \n" + doEncrypt);
        // 私钥解密
        final String s = Sm2.doDecrypt(doEncrypt, privateKey);
        System.out.println("解密:\n" + s);
    }

image-1661078949316

签名验签、获取椭圆曲线点
更多加密方式参考: https://github.com/JuneAndGreen/sm-crypto#readme

前端代码实现 - vue

安装依赖

npm install --save sm-crypto

获取密钥对

const sm2 = require('sm-crypto').sm2
let keypair = sm2.generateKeyPairHex()
publicKey = keypair.publicKey // 公钥
privateKey = keypair.privateKey // 私钥

// 自定义随机数,参数会直接透传给 jsbn 库的 BigInteger 构造器
// 注意:开发者使用自定义随机数,需要自行确保传入的随机数符合密码学安全
let keypair2 = sm2.generateKeyPairHex('123123123123123')
let keypair3 = sm2.generateKeyPairHex(256, SecureRandom)
let verifyResult = sm2.verifyPublicKey(publicKey) // 验证公钥

加密解密

// 这里使用Java生成的密钥
// 后端生成密钥
const privateKey = 'a7a9846bbb015f8192bae355be4013d7b7b2bdcf56033b990d58bb5a7541f518'
const publicKey = '048ff6380b4db5c9fc9d80fc5e30bde049c12222c56b9085aa1f1c0b53cabd09e72dc5690110e5b57fc3ff88111d0d161723bcb6365c33cef70d3dbbdf32c7038f'


const sm2 = require('sm-crypto').sm2
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
let encryptData = sm2.doEncrypt(msgString, publicKey, cipherMode) // 加密结果
let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) // 解密结果
// 指定输出类型
// encryptData = sm2.doEncrypt(msgArray, publicKey, cipherMode) // 加密结果,输入数组
// decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode, {output: 'array'}) // 解密结果,输出数组

前端代码

image-1661080078970

页面查看

image-1661080196004

最终封装

/**
 * 前端加密
 * @param text
 * @returns {*}
 */
export function encrypt(text) {
  return sm2.doEncrypt(text, publicKey, 1) // 加密结果
}

/**
 * 前端解密
 * @param text
 * @returns {*}
 */
export function decrypt(text) {
  return sm2.doDecrypt(text, privateKey, 1) // 加密结果
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值