1、Maven引入以下依赖

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.70</version>
        </dependency>

  <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.16</version>
        </dependency>

2、sm2示例代码

 public static void main(String[] args) {
        String text = "我是一段测试aaaa";

        String publicKey = "xxx";
        String privateKey = "cc";
        //公钥加密
        text = encodeByPublicKey(publicKey, privateKey, text);
        System.out.println(text);
        //私钥解密
        text = decryptData(publicKey, privateKey, text);
        System.out.println(text);

    }

    public static String decryptData(String publicKey, String privateKey, String encryptData) {
        if (StrUtil.isBlank(encryptData)) {
            throw new MyException("解密串为空,解密失败");
        }
        SM2 sm2 = SmUtil.sm2(ECKeyUtil.toSm2PrivateParams(privateKey), ECKeyUtil.toSm2PublicParams(publicKey));
        // BC库解密时密文开头必须带04,如果没带04则需补齐
        if (!encryptData.startsWith("04")) {
            encryptData = "04".concat(encryptData);
        }
        byte[] decryptFromBcd = sm2.decryptFromBcd(encryptData, KeyType.PrivateKey);
        if (decryptFromBcd != null && decryptFromBcd.length > 0) {
            return StrUtil.utf8Str(decryptFromBcd);
        } else {
            throw new MyException("密文解密失败");
        }
    }

    /**
     * 加密
     *
     * @param publicKey
     * @param privateKey
     * @param data
     */
    public static String encodeByPublicKey(String publicKey, String privateKey, String data) {
        SM2 sm2 = SmUtil.sm2(ECKeyUtil.toSm2PrivateParams(privateKey), ECKeyUtil.toSm2PublicParams(publicKey));
        String encryptBcd = sm2.encryptBcd(data, KeyType.PublicKey);
        // 这里的处理前端也可以处理,这个就看怎么约定了,其实都无伤大雅
        if (StrUtil.isNotBlank(encryptBcd)) {
            // 生成的加密密文会带04,因为前端sm-crypto默认的是1-C1C3C2模式,这里需去除04才能正常解密
            if (encryptBcd.startsWith("04")) {
                encryptBcd = encryptBcd.substring(2);
            }
            // 前端解密时只能解纯小写形式的16进制数据,这里需要将所有大写字母转化为小写
            encryptBcd = encryptBcd.toLowerCase();
        }
        return encryptBcd;
    }

    /**
     * 获取公钥秘钥对
     */
    public static void getPrivateKeyPublicKey() {
        SM2 sm2 = SmUtil.sm2();
        // 私钥:这个保存好,切记不要泄漏,真的泄露了就重新生成一下
        byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());
        // 公钥:这个是前后端加密用的,不压缩选择带04的,不带04到时候前端会报错
        byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);
        Console.log("公钥:\n{}", HexUtil.encodeHexStr(publicKey));
        Console.log("私钥:\n{}", HexUtil.encodeHexStr(privateKey));
    }

3、 sm4示例

    public static void main(String[] args) {
        String content = "test中文1111@3水电费";
        
        //获取初始化key
        //String key=initKey();
        
        String key = "QBBo4bHjs8JhvzNpNoDChw==";
        
        byte[] bytes = Base64.decodeBase64(key);
        //初始化sm4工厂
        SymmetricCrypto sm4 = SmUtil.sm4(bytes);


        //加密
        String encryptHex = sm4.encryptHex(content);
        //解密
        String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        System.out.println(encryptHex);
        System.out.println(decryptStr);
    }

//初始化key
public static String initKey(){
            SymmetricCrypto sm4 = SmUtil.sm4();
            byte[] bytes = sm4.getSecretKey().getEncoded();
        String x = Base64.encodeBase64String(bytes);
        System.out.println(x);
        return x;
}

更多推荐