当前位置:   article > 正文

SM2——适用于前后端(java+vue)公用的SM2国密加解密传输_java集成sm2

java集成sm2

一、SM2国密加解密算法

1.1、pom文件引入依赖包

 <dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-jdk18on</artifactId>
     <version>1.72</version>
 </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

1.2、SM2加解密工具类

  • SM2加解密工具类

    package com.xz.utils;
    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 java.math.BigInteger;
    import java.security.*;
    import java.security.spec.ECGenParameterSpec;
    import java.util.HashMap;
    import java.util.Map;
    
    
    /**
     * 适用于前后端公用的SM2秘钥生成、加解密工具类
     */
    public class SimpSM2Util {
        /**
         * 公钥常量
         */
        public static final String KEY_PUBLIC_KEY = "publicKey";
        /**
         * 私钥返回值常量
         */
        public static final String KEY_PRIVATE_KEY = "privateKey";
    
        /**
         * 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;
        }
     
        /**
         * 生成密钥
         */
        public static Map<String, String> createKey() throws Exception{
            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()));
            Map<String, String> result = new HashMap<>();
            result.put(KEY_PUBLIC_KEY, Hex.toHexString(p.getQ().getEncoded(false)));
            result.put(KEY_PRIVATE_KEY, Hex.toHexString(s.getD().toByteArray()));
            return result;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

1.3、测试类

  • 测试类

    public static void main(String[] args) throws Exception {
          Map<String, String> key = createKey();
           String publicKey = key.get(KEY_PUBLIC_KEY);
           System.out.println("公钥:"+publicKey);
           String privateKey = key.get(KEY_PRIVATE_KEY);
           System.out.println("私钥:"+privateKey);
    
           String str="hello java123456";
           System.out.println("加密前结果:"+str);
           String encrypt = encrypt(publicKey, str);
           System.out.println("加密后结果:"+encrypt);
           String decrypt = decrypt(privateKey, encrypt);
           System.out.println("解密后结果:"+decrypt);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 测试结果,如下图所示:
    在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/672418
推荐阅读
相关标签
  

闽ICP备14008679号