• 加密国密非对称SM2


    国家密码管理局于2010年12月17日发布了SM2算法,并要求现有的基于RSA算法的电子认证系统、密钥管理系统、应用系统进升级改造,使用支持国密SM2算法的证书。

    我国现阶段使用的国密SM2算法是在椭圆曲线密码理论基础进行改进而来,其加密强度比RSA算法(2048位)更高。

    前段vue + 后端springboot;

      思路: 后端使用hutools工具生成公私钥(公130,私64);并且可以进行加解密。

        前段使用的公钥加密,生成密文后,但是在后端解密的时候,解不出来。原因需要在密文前面加04

    1.前段加密:

    后端会生成密钥对(公钥(publicKey),私钥(privateKey))
    vue使用sm2加密
    
    1.安装下载依赖:npm install --save sm-crypto
    下载报错的话可以用淘宝镜像下载:npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
    2.sm2在vue中使用: 
    
    const sm2 = require('sm-crypto').sm2
    const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
    
    let encryptData = sm2.doEncrypt('需要加密的字符', publicKey, cipherMode) // 加密结果
    let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) // 解密结果
    //给后端(java)传值时需要在加密的密文前面加04 (`04${encryptData}`),这样后端才能解密正确不报错;

     1.1 vue 引入js 

      vue 中 

    <script>
    import { sm2Encrypt, sm2Decrypt } from '@/utils/sm2Encrypt'

    sm2Encrypt.js

    const publicKey = '130'
    
    const privateKey = '64'
    
    const sm2 = require('sm-crypto').sm2
    const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
    
    
    // 加密
    export function sm2Encrypt(txt) {
      let encryptData = sm2.doEncrypt(txt, publicKey, cipherMode) // 加密结果
      return encryptData
    
    }
    
    // 解密
    export function sm2Decrypt(txt) {
      let decryptData = sm2.doDecrypt(txt, privateKey, cipherMode) // 解密结果
      return decryptData;
    
    }
    View Code

    2.后端解密

    2.1pom中引入依赖

     <!-- hutool工具类 -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.7.4</version>
            </dependency>
    
            <!-- 第三方加密功能依赖sm2 -->
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcprov-jdk15to18</artifactId>
                <version>1.69</version>
            </dependency>
         <!--
        <dependency>
          <groupId>org.bouncycastle</groupId>
          <artifactId>bcprov-jdk15on</artifactId>
          <version>1.56</version>
        </dependency>
    -->

    相关代码:

    package com.sinosoft;
    
    import cn.hutool.core.util.HexUtil;
    import cn.hutool.core.util.StrUtil;
    import cn.hutool.crypto.BCUtil;
    import cn.hutool.crypto.SmUtil;
    import cn.hutool.crypto.asymmetric.KeyType;
    import cn.hutool.crypto.asymmetric.SM2;
    import lombok.extern.slf4j.Slf4j;
    import org.bouncycastle.crypto.engines.SM2Engine;
    import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.nio.charset.Charset;
    //import org.junit.runner.RunWith;
    
    
    /**
     * TODO
     *
     * @author zhaoJs
     * @version 1.0
     * @date 2022/9/2 15:07
     */
    @SpringBootTest (classes = Sm2Test.class)
    @RunWith(SpringRunner.class)
    @Slf4j
    public class Sm2Test {
        String privateKey = "00ac90ec091563b319bdf2e449df659940f24e14beaf09935a92b260fa68c6c8ac";
        String publicKey = "0462a7f3ed9cc136465353dffcf0e253723e3b0c1525cf47860901c0c4ba57c8d984bfc6cb0d1d9764498b41e58fd0040a9920d904ad442495e154d2fe68fd2720";
        String content = "测试";
    
        //公私钥生成
        @Test
        public void createSM2Key(){
    
            SM2 sm2 = SmUtil.sm2();
            // sm2的加解密时有两种方式即 C1C2C3、 C1C3C2,
            sm2.setMode(SM2Engine.Mode.C1C3C2);
            // 生成私钥
            String privateKey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey()));
            // 生成公钥
            String publicKey = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false));
            
            log.info("privateKey:" + privateKey);
            log.info("publicKey:" + publicKey);
    
        }
        //公钥加密
        @Test
        public void encrypt(){
            SM2 sm2 = SmUtil.sm2(null, publicKey);         
            sm2.setMode(SM2Engine.Mode.C1C3C2);
            // 返回值的字符串,需要注意此处加密后密文为16进制,否则前端解密前需要先转换格式
            String encryptStr = sm2.encryptHex(new String(content), Charset.forName("utf-8"), KeyType.PublicKey);
            log.info("encryptStr:" + encryptStr);
        }
        //私钥解密
        @Test
        public void decrypt(){
         // 如果是前段vue传来的 密文,需要在密文前加04 String encryptStr
    = "04f0d63500e8f56243462b17c9489c7ea7bbbb10271f45066cc150e2da934fca72abe396b05639fac1192630c27bd7d3ff553c0f43260e8cdb84c5c6594701f75ce96a49ba0d16368acdc3ef16c211bc638cc47caf05214e8e302c8ddb3798534044d1d6204277"; // 解密 SM2 sm2 = SmUtil.sm2(privateKey, publicKey); sm2.setMode(SM2Engine.Mode.C1C3C2); //String newBody1 = StrUtil.utf8Str(sm2.decryptFromBcd(d, KeyType.PrivateKey)); String decryptStr = sm2.decryptStr(encryptStr, KeyType.PrivateKey, Charset.forName("utf-8")); log.info("decryptStr:" + decryptStr); } }

     使用的原生的sm2加密参考

     加密是为了防止信息被泄露,而签名是为了防止信息被篡改。

    参考:

    SM2 java+hutool方法示例(重点参考)

    一文告诉你,国密SM2算法有多优秀

    国密SM2的前端加密,后端解密(Java版本)及SM3 摘要加密

    国密SM2前端VUE,后端Hutool工具的搭配

    前端Vue使用SM2加密、解密方法

    vue/java使用国密SM2加密

    使用hutool工具类国密算法SM2实现

    基于hutool实现非对称加密(RSA和国密SM2)的加解密和加签验签

    RSA加密、解密、签名、验签的原理及方法

  • 相关阅读:
    SQL SERVER导入Excel csv
    微信付款码扫码枪支付
    idftp
    不正常地定义参数对象。提供了不一致或不完整的信息
    sql 日志文件截断收缩
    sql server 新语法 收藏
    SQL SERVER 2019新功能
    SQL SERVER 死锁
    rad 10.2
    TXMLDocument 创建空值节点不要缩写
  • 原文地址:https://www.cnblogs.com/nextgg/p/16648745.html
Copyright © 2020-2023  润新知