适用于前后端公用的SM2国密加密传输, JAVA + VUE

这篇具有很好参考价值的文章主要介绍了适用于前后端公用的SM2国密加密传输, JAVA + VUE。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

由于等保和多个系统间的数据传输加密, 写了一个共有的前端与后端, 后端与后端,的通用算法SM2简单加密,  不需要验签, 几行代码搞定. 

引包, 测试好几遍, 这个包适合jdk1.8使用

1、后端代码示例

引包,

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk18on</artifactId>
            <version>1.72</version>
        </dependency>

没有意外就应该直接能用下面代码了

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.junit.Test;

import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;


/**
 * 简单的sm2
 */
public class SimpSM2Util {

    /**
     * SM2加密算法
     * @param publicKey     公钥
     * @param data          明文数据
     * @return
     */
    public static String encrypt(String publicKey, String data) {
        // 获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        // 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数N
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        //提取公钥点
        ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);

        SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
        // 设置sm2为加密模式
        sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));

        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes();
            arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
        } catch (Exception e) {
            System.out.println("SM2加密时出现异常:"+e.getMessage());
        }
        return Hex.toHexString(arrayOfBytes);

    }

    /**
     * SM2解密算法
     * @param privateKey        私钥
     * @param cipherData        密文数据
     * @return
     */
    public static String decrypt(String privateKey, String cipherData) {
        // 使用BC库加解密时密文以04开头,传入的密文前面没有04则补上
        if (!cipherData.startsWith("04")){
            cipherData = "04" + cipherData;
        }
        byte[] cipherDataByte = Hex.decode(cipherData);
        BigInteger privateKeyD = new BigInteger(privateKey, 16);
        //获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        //构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);

        SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
        // 设置sm2为解密模式
        sm2Engine.init(false, privateKeyParameters);

        String result = "";
        try {
            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
            return new String(arrayOfBytes);
        } catch (Exception e) {
            System.out.println("SM2解密时出现异常:"+e.getMessage());
        }
        return result;
    }

    /*@Test  
    // 生成密钥
    public void createKey() throws Exception{
        //String M="encryption standard111111111111111111111111111111";
        SimpSM2Util sm2 = new SimpSM2Util();
        ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
        // 获取一个椭圆曲线类型的密钥对生成器
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
        // 使用SM2参数初始化生成器
        kpg.initialize(sm2Spec);
        // 获取密钥对
        KeyPair keyPair = kpg.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        BCECPublicKey p=(BCECPublicKey)publicKey;
        System.out.println("publicKey:"+Hex.toHexString(p.getQ().getEncoded(false)));

        PrivateKey privateKey = keyPair.getPrivate();
        BCECPrivateKey s=(BCECPrivateKey)privateKey;
        System.out.println("privateKey:"+Hex.toHexString(s.getD().toByteArray()));

    }*/
}

    publicKey:04aa909915f87880507e3de515220cc8f82b1c5693f56a0475b3b48ff7448c229734cd724e603000dd78569faa9fbc1eeb93a6d836190a0ee734e2d9e74d804f28
    privateKey:00a684d832831d5371d2ff9de6a021a33fb396451e74e0ffe0d415c298b36876fe

加密:  SimpSM2Util.encrypt("共有密钥", "明文"); 

解密:  SimpSM2Util.decrypt("私有密钥", "密文");

后端代码使用一个工具类, 可参考


import org.bouncycastle.crypto.engines.SM2Engine;

/**
 * 简单单例SM2加解密, 配合前端
 */
public class LoSM2 {

    private static String ECNameModel = "sm2p256v1";
    private static SM2Engine.Mode CipherMode = SM2Engine.Mode.C1C3C2;
    private final String privateKey;
    private final String publicKey;

    private LoSM2(String privateKey, String publicKey){
        this.privateKey = privateKey;
        this.publicKey = publicKey;
    }

    private volatile static LoSM2 instance = null;

    public static LoSM2 getInstance(){
        if(instance == null){
            throw new RuntimeException("请InitKey初始化密钥!!!");
        }
        return instance;
    }

    /**
     * SM2初始密钥(私钥,公钥)
     * @param privateKey
     * @param publicKey
     * @return
     */
    public static LoSM2 InitKey(String privateKey, String publicKey) {
        if(instance == null){
            synchronized(LoSM2.class){
                if(instance == null){
                    instance = new LoSM2(privateKey, publicKey);
                }
            }
        }
        return instance;
    }

    private static class SM2SimpSelfLoader {
        private static final LoSM2 instance = InitKey("", "");
    }

    private static boolean IsInitKey(){
        if(instance == null) {
            throw new RuntimeException("请InitKey初始化密钥!!!");
        }else {
            return true;
        }
    }

    /**
     * SM2加密
     * @param cleartext          明文数据
     */
    public String encrypt(String cleartext) {
        if(!IsInitKey())
            return "";
        return SimpSM2Util.encrypt(instance.publicKey, cleartext);        
    }

    /**
     * SM2解密
     * @param cipherData        密文数据
     */
    public static String decrypt(String cipherData) {
        if(!IsInitKey())
            return "";
        return SimpSM2Util.decrypt(instance.privateKey, cipherData);
    }

}

2、前端代码示例

安装sm-crypto包:   npm install --save sm-crypto

前端加解密更简单,  引包后就能用

let txt='简单加密不要验签'  //要加密的字段
const sm2 = require('sm-crypto').sm2
const cipherMode = 1;// 1 - C1C3C2,0 - C1C2C3,默认为1
var publicKey =  "04aa909915f87880507e3de515220cc8f82b1c5693f56a0475b3b48ff7448c229734cd724e603000dd78569faa9fbc1eeb93a6d836190a0ee734e2d9e74d804f28";
// 加密结果            
let encryptData = sm2.doEncrypt(txt, publicKey, cipherMode);
// 解密
sm2.doDecrypt(txt, privateKey, cipherMode);

适合简单的传输加密

3、避坑指南

在引用 bcprov-jdk18on 包的时候, 有可能存在版本冲突, 或本地安全问题,  这个是我在返回切换工程遇到的问题 

可以尝试把 bcprov-jdk18on-1.72.jar 加入mvn的import的sdks里面

java sm2,前端,后端,随笔,java,vue,安全

还可以试试 mvn idea:module

或者试试  mvn: idea:idea文章来源地址https://www.toymoban.com/news/detail-592598.html

到了这里,关于适用于前后端公用的SM2国密加密传输, JAVA + VUE的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用 Java Bouncy Castle实现国密算法SM4、SM3以及SM2的加密

    国密算法的实现借助了Java库函数 Bouncy Castle,加密库安装使用教程请参考链接 SM4,又称为商密算法,是一种分组密码算法,于2012年由中国密码技术研究中心(中国密码学会成员)发布,目前已成为我国国家密码算法,并在多个领域得到了广泛的应用。SM4算法采用了32轮迭代结

    2024年02月16日
    浏览(62)
  • 小程序 实现 国密 sm2 加密

    第一步:进入微信小程序项目目录下,输入cmd    第二步:加载插件包 第三步:加载成功之后,会参生这个文件夹     第四步:然后在对应的js文件中引入miniprogram-sm-crypto/index.js   第五步: 加密方式,加密方法  

    2024年02月16日
    浏览(34)
  • 前端sm2国密加密解密

    1.下载国密包 2.获取后端的公钥 注sm-crypto使用BC库加解密前端密钥与后端密钥是两队,非常规的base64密钥 前端公钥需要在前面加04占位否则无法解密 3.前端使用公钥进行加密 生成的加密串加04方便后端解密 4.前端使用私钥解密

    2024年02月11日
    浏览(58)
  • 国密SM2前端加密解密示例

    目录 一、 安装sm2依赖 二、编写代码 1、data中绑定数据 2、公钥加密 3、私钥解密 4、按钮绑定一下,数据可见一下 三、完整代码 要改变的数据phone和过程数据copyphone,公钥publicKey和私钥privateKey 具体生成测试公钥私钥可参照SM2加解密 C1为65字节第1字节为压缩标识,这里固定为

    2024年02月03日
    浏览(64)
  • vue普通加密以及国密SM2、SM3、sm4的使用

    sm-crypto:https://www.npmjs.com/package/sm-crypto 1. SM2是非对称加密算法 它是基于椭圆曲线密码的公钥密码算法标准,其秘钥长度256bit,包含数字签名、密钥交换和公钥加密,用于替换RSA/DH/ECDSA/ECDH等国际算法。可以满足电子认证服务系统等应用需求,由国家密码管理局于2010年12月17号

    2023年04月09日
    浏览(43)
  • OpenSSL 3.1.1 ECC 加密、解密、签名、验签(国密 sm2、sm3)

    openssl 3 默认废弃了 旧版本 (opessl 1.x) 的部分api 导致部分旧ecc 代码无法使用(可以通过配置编译选项打开) ,这里展示如何使用新接口用ECC 进行加密解密。 新接口是真的方便,基本上你都不需要懂啥密码学知识,对我们这种密码白痴来说太好了 头文件 生成密钥对 导出公

    2024年02月05日
    浏览(57)
  • 医保移动支付加密解密请求工具封装【国密SM2SM4】

    医保移动支付加密解密请求工具封装 定点医药机构向地方移动支付中心发起费用明细上传、支付下单、医保退费等交易时需要发送密文,由于各大医疗机构厂商的开发语各不相同,可能要有java的、c#的、python的、pb的、nodjs的、php的、还可能有Delphi的等。。。。很多开发语言

    2024年01月21日
    浏览(85)
  • 国密SM2算法的加密签名消息语法封装解析p7格式signedData

    前文可参考:SM2算法的加密签名消息语法规范(三)如何构造signedData_天对地,雨对风的博客-CSDN博客系列。 这里直接讲openssl asn1解析和封装的部分代码。 国密 p7格式标准,参考:GMT0010-2012 1、p7 签名结构:  编写结构体GMTSignedData.h 注意:SM2_SignedData_st结构中的sign类型修改为

    2024年02月11日
    浏览(41)
  • 国密算法 SM2 公钥加密 数字签名 密钥交换 全网最高效的开源python代码

    此前发布过SM2、SM3、SM4、ZUC等文章,以及开源的完整python代码。近些天看到一篇电子科大兰同学的硕士毕业论文(兰修文. ECC计算算法的优化及其在SM2实现中的运用[D]. 成都: 电子科技大学, 2019),文中采用预计算加速SM2椭圆曲线基点点乘,将这个思路用python代码实现后,实测

    2024年02月09日
    浏览(47)
  • JAVA集成国密SM2

    国密算法概述:https://blog.csdn.net/qq_38254635/article/details/131801527 SM2椭圆曲线公钥密码算法 为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。

    2024年02月13日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包