Java 使用国密算法加密


import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.google.common.base.Charsets;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.*;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class Test {

    /**
     * sm2 加密解密
     */
    public static class SM2Util{
        static final BouncyCastleProvider bc = new BouncyCastleProvider();

        /**
         * 生成key
         * @return
         */
        public static Map<String,Object> generateKey(){
            KeyPair pair = SecureUtil.generateKeyPair("SM2");
            Map<String,Object> map = new HashMap<>();
            map.put("publicKey",pair.getPublic());
            map.put("privateKey",pair.getPrivate());
            return map;
        }

        /**
         * 加密
         * @param data
         * @param aPublic
         * @return
         */
        public static String encrypt(String data, PublicKey aPublic){
            SM2 sm2 = SmUtil.sm2();
            sm2.setPublicKey(aPublic);
            String s = sm2.encryptBcd(data, KeyType.PublicKey);
            return s;
        }

        /**
         * 解密
         * @param data
         * @param privateKey
         * @return
         */
        public static String decrypt(String data, PrivateKey privateKey){
            SM2 sm2 = SmUtil.sm2();
            sm2.setPrivateKey(privateKey);
            return StrUtil.utf8Str(sm2.decryptFromBcd(data,KeyType.PrivateKey));
        }


        /**
         * 从字符串中读取 私钥 key
         * @param privateKeyStr String
         * @return PrivateKey
         */
        public static PrivateKey strToPrivateKey(String privateKeyStr){
            PrivateKey privateKey = null;
            try {
                byte[] encPriv = Base64.decode(privateKeyStr);
                KeyFactory keyFact = KeyFactory.getInstance("EC", bc);
                privateKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(encPriv));

            }catch (Exception e){
                e.printStackTrace();
            }
            return privateKey;
        }

        /**
         * 从字符串中读取 公钥 key
         * @param publicKeyStr String
         * @return PublicKey
         */
        public  static PublicKey strToPublicKey(String publicKeyStr){
            PublicKey publicKey =  null;
            try {
                byte[] encPub = Base64.decode(publicKeyStr);
                KeyFactory keyFact = KeyFactory.getInstance("EC", bc);
                publicKey = keyFact.generatePublic(new X509EncodedKeySpec(encPub));
            }catch (Exception e){
                e.printStackTrace();
            }
            return publicKey;
        }


        /**
         * 公钥 key  转文件
         * @param publicKey PublicKey
         * @param path String
         */
        public static void exportPublicKey(PublicKey publicKey,String path){
            File file = new File(path);
            try {
                File fileParent = file.getParentFile();
                if(!fileParent.exists()){
                    fileParent.mkdirs();
                }
                file.createNewFile();
                byte[] encPub = publicKey.getEncoded();
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(encPub);
                fos.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }

        /**
         * 私钥 key 转文件
         * @param privateKey PrivateKey
         * @param keyPath String
         */
        public static void exportPrivateKey(PrivateKey privateKey, String keyPath){
            File file = new File(keyPath);
            try {
                File fileParent = file.getParentFile();
                if(!fileParent.exists()){
                    fileParent.mkdirs();
                }
                file.createNewFile();
                byte[]  encPriv = privateKey.getEncoded();
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(encPriv);
                fos.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }

        /**
         * 读取公钥文件
         * @param path
         * @return
         */
        public static PublicKey importPublicKey(String path){
            File file = new File(path);
            try {
                if (!file.exists()){
                    return null;
                }
                FileInputStream fis = new FileInputStream(file);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[16];
                int size;
                while ((size = fis.read(buffer)) != -1){
                    baos.write(buffer,0,size);
                }
                fis.close();
                byte[] bytes = baos.toByteArray();
                String publicKeyStr = Base64.encode(bytes);

                return strToPublicKey(publicKeyStr);
            }catch (IOException e){
                e.printStackTrace();
            }
            return null;
        }


        /**
         * 读取私钥文件
         * @param keyPath
         * @return
         */
        public static PrivateKey importPrivateKey(String keyPath){
            File file = new File(keyPath);
            try {
                if (!file.exists()){
                    return null;
                }
                FileInputStream fis = new FileInputStream(file);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte buffer[] = new byte[16];
                int size;
                while ((size = fis.read(buffer)) != -1){
                    baos.write(buffer,0,size);
                }
                fis.close();

                byte[]  bytes = baos.toByteArray();
                String privateKeyStr = Base64.encode(bytes);

                return strToPrivateKey(privateKeyStr);
            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }


        public static void test1(){
            System.out.println("==============SM2 随机密钥对加密开始===============");
            String text = "测试1111111";

            SM2 sm2 = SmUtil.sm2();

            //第一种 使用随机密钥对
            String s = sm2.encryptBcd(text, KeyType.PublicKey);
            System.out.println(s);
            String s1 = StrUtil.utf8Str(sm2.decryptFromBcd(s, KeyType.PrivateKey));
            System.out.println(s1);
            System.out.println("==============SM2 随机密钥对加密结束===============");
        }

        public static void test2(){
            System.out.println("==============SM2 自定义密钥对加密开始===============");
            String text = "测试2222222";
            SM2 sm = SmUtil.sm2();
            String privateKeyBase64 = sm.getPrivateKeyBase64();
            String publicKeyBase64 = sm.getPublicKeyBase64();
            System.out.println("SM2 密钥:"+privateKeyBase64);
            System.out.println("SM2 公钥:"+publicKeyBase64);

            // 通过公钥进行加密
            SM2 sm2 = SmUtil.sm2(null, publicKeyBase64);
            String encryptStr = sm2.encryptBase64(text, KeyType.PublicKey);
            System.out.println("SM2 加密后报文:"+ encryptStr);

            // 通过密钥解密
            SM2 sm22 = SmUtil.sm2(privateKeyBase64, null);
            String s = sm22.decryptStr(encryptStr, KeyType.PrivateKey);
            System.out.println("SM2 解密后报文:"+ s);
            System.out.println("==============SM2 自定义密钥对加密结束===============");
        }


        public static void test3() {
            System.out.println("==============SM2 文件密钥对加密开始===============");
            String text = "测试aaaaaaaaa";
            System.err.println("原文:"+text);
            Map<String,Object> keyMap = generateKey();
            //公钥 key 和私钥 key 转文件
            exportPublicKey((PublicKey) keyMap.get("publicKey"),"F:\\sm2\\public_key.pem");
            exportPrivateKey((PrivateKey) keyMap.get("privateKey"),"F:\\sm2\\private_key.pem");

            //从pem文件里 读取 公钥 和 私钥
            PublicKey pubk2 = importPublicKey("F:\\sm2\\public_key.pem");
            PrivateKey priK2 = importPrivateKey("F:\\sm2\\private_key.pem");

            //公钥加密
            String sm2text = encrypt(text,pubk2);
            System.err.println("SM2 加密后报文:"+sm2text);

            //私钥解密
            System.err.println("SM2 解密后报文:"+decrypt(sm2text,priK2));
            System.out.println("==============SM2 文件密钥对加密结束===============");

        }

    }


    /**
     * sm4 加密解密
     */
    public static class SM4Util{
        /**
         * 生成key
         * @return
         */
        public static String generateKey(){
            return RandomUtil.randomString(16);
        }

        /**
         * 加密
         * @param data
         * @param key
         * @return
         */
        public static String encrypt(String data, String key){
            SymmetricCrypto sm4_en =SmUtil.sm4(key.getBytes(Charsets.UTF_8));
            return sm4_en.encryptBase64(data);
        }

        /**
         * 解密
         * @param data
         * @param key
         * @return
         */
        public static String decrypt(String data, String key){
            SymmetricCrypto sm4_de =SmUtil.sm4(key.getBytes(Charsets.UTF_8));
            return sm4_de.decryptStr(data, Charsets.UTF_8);
        }

        public static void test(){
            System.out.println("==============SM4 加密开始===============");
            String key = generateKey();
            String ens = encrypt("测试123456",key);
            System.out.println("SM4 加密:"+ens);
            System.out.println("SM4 解密:"+decrypt(ens,key));
            System.out.println("==============SM4 加密结束===============");
        }
    }



    public static void main(String[] args) {
        //sm2 加密解密
        SM2Util.test1();
        SM2Util.test2();
        SM2Util.test3();

        //sm3 加密
        //需要注意的是 SM3 算法是不可逆的,只能从原文得到摘要签名,不能从摘要签名 反向得到原文
        System.out.println("==============SM3 加密开始===============");
        System.out.println("SM3 加密后报文:"+ SmUtil.sm3("123456"));
        System.out.println("==============SM3 加密结束===============");

        //sm4 加密解密
        SM4Util.test();

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值