一:SM2简介

SM2是中国密码学算法标准中的一种非对称加密算法(包括公钥私钥)。SM2主要用于数字签名密钥交换加密解密密码学

CFCA

二:Java

<dependency>
	&lt;groupId&gt;org.apache.commons</groupId&gt;
	<artifactId&gt;commons-lang3</artifactId&gt;
	<version&gt;3.9</version&gt;
</dependency&gt;

<dependency&gt;
	<groupId>com.cfca</groupId>
	<artifactId>SADK</artifactId>
	<version>3.2.1.3</version>
</dependency>
public class SM2Util {

    private static final String PVK_FILE = ".pvk";
    private static final String PUB_FILE = ".puk";


    /**
     * 加密数据
     * @param publicKey
     * @param data
     */
    public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {
        byte[] result = null;
        SM2Toolkit sm2Toolkit = new SM2Toolkit();
        SM2PublicKey sm2PublicKey = (SM2PublicKey)publicKey;
        result = sm2Toolkit.SM2EncryptData(sm2PublicKey, data);
        return result;
    }

    public static byte[] decryptString(PrivateKey privateKey, String base64Text) throws Exception {
        SM2Toolkit sm2Toolkit = new SM2Toolkit();
        SM2PrivateKey sm2PrivateKey = (SM2PrivateKey)privateKey;
        return sm2Toolkit.SM2DecryptData(sm2PrivateKey, BASE64Toolkit.decode(base64Text));
    }

    public static void sm4EncryptFile(String key, String inFile, String outFile) throws Exception{
        SM4Toolkit toolkit = new SM4Toolkit();
        toolkit.SM4Init(key.getBytes(), key.getBytes());
        toolkit.SM4EncryptFile(inFile, outFile);
    }

    public static boolean sM4DecryptFile(String key, String inFile, String outFile) throws Exception {
        SM4Toolkit toolkit = new SM4Toolkit();
        toolkit.SM4Init(key.getBytes(), key.getBytes());
        return toolkit.SM4DecryptFile(inFile, outFile);
    }

    /**
     * 签名
     * @param privateKey
     */
    public static String singnString(PrivateKey privateKey, byte[] srcBytes) throws Exception {
        SM2Toolkit sm2Toolkit = new SM2Toolkit();
        SM2PrivateKey sm2PrivateKey = (SM2PrivateKey)privateKey;
        String result = BASE64Toolkit.encode(sm2Toolkit.SM2Sign(sm2PrivateKey, srcBytes));
        return result;
    }

    public static String sm2SignFile(String filePath, String privateKeyPath) throws Exception {
        SM2Toolkit sm2Toolkit = new SM2Toolkit();
        byte[] privateBytes = readKey(privateKeyPath);

        SM2PrivateKey sm2PrivateKey = (SM2PrivateKey)sm2Toolkit.SM2BuildPrivateKey(BASE64Toolkit.encode(privateBytes));
        byte[] hash = SM3Toolkit.SM3HashFile(sm2PrivateKey.getSM2PublicKey(), filePath);
        String result = BASE64Toolkit.encode(BCSoftSM2.sign(hash, sm2PrivateKey.dBigInteger(), true));
        return result;
    }


    /**
     * 文件验签
     * @param outfilePath
     * @param keyPath
     * @param singStr
     * @return
     */
    public static boolean verify(String outfilePath, String keyPath, String singStr) {
        boolean result = false;

        try {
            SM2Toolkit toolkit = new SM2Toolkit();
            SM2PublicKey sm2PublicKey = (SM2PublicKey)toolkit.SM2BuildPublicKey(BASE64Toolkit.encode(readKey(keyPath)));
            byte[] hash = SM3Toolkit.SM3HashFile(sm2PublicKey, outfilePath);
            result = toolkit.SM2VerifyHash(sm2PublicKey, hash, BASE64Toolkit.decode(singStr));
        } catch (Exception e) {
            throw new RuntimeException("文件验签失败");
        }

        return result;
    }


    /**
     * 读取私钥
     * @param keyPath
     * @return
     */
    public static SM2PrivateKey buildPrivateKey(String keyPath) throws Exception {
        if (!keyPath.endsWith(PVK_FILE)) {
            keyPath += PVK_FILE;
        }

        byte[] privateKeyByte = readKey(keyPath);
        SM2Toolkit sm2Toolkit = new SM2Toolkit();
        SM2PrivateKey sm2PrivateKey = (SM2PrivateKey)sm2Toolkit.SM2BuildPrivateKey(BASE64Toolkit.encode(privateKeyByte));
        return sm2PrivateKey;
    }

    /**
     * 读取公钥
     * @param keyPath
     * @return
     */
    public static SM2PublicKey buildPublicKey(String keyPath) throws Exception {
        if (!keyPath.endsWith(PUB_FILE)) {
            keyPath += PUB_FILE;
        }

        byte[] privateKeyByte = readKey(keyPath);
        SM2Toolkit sm2Toolkit = new SM2Toolkit();
        SM2PublicKey sm2PublicKey = (SM2PublicKey)sm2Toolkit.SM2BuildPublicKey(BASE64Toolkit.encode(privateKeyByte));
        return sm2PublicKey;
    }

    /**
     * 读取秘钥
     * @param filePath
     */
    public static byte[] readKey(String filePath) throws Exception {
        try(FileInputStream is = new FileInputStream(filePath)) {
            byte[] out = new byte[is.available()];
            byte[] buffer = new byte[1024];
            int len;
            for (int offset = 0; (len = is.read(buffer, 0, buffer.length)) != -1; offset += len) {
                System.arraycopy(buffer, 0, out, offset, len);
            }
            return out;
        }
    }


    public static void main(String[] args) throws Exception {
        SM2Toolkit toolkit = new SM2Toolkit();
        KeyPair keyPair = toolkit.SM2GenerateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();


        // 1. 对源文件进行签名(最终会作为签名文件和数据zip一起放到新的.zip中去)
        String zipPath = "/Temp/data.zip";
        String tempZipPath = "/Temp/Activiti/data.zip";
        String signguare = sm2SignFile(zipPath, "xxx.pvk");

        // 2. 对秘钥加密(最终将将加密的秘钥作为压缩包文件中的一部分)
        String verifyChars = "1234567890abcdefghijkmnopqrstuvwxyz";
        String encryptKey = RandomStringUtils.random(16, verifyChars).toUpperCase();
        
        byte[] encrypt = encrypt(buildPublicKey("/Temp/xxx.puk"), random16.getBytes());
        byte[] encryptKeyBytes = BASE64Toolkit.encode(encrypt).getBytes();

        // 3. 加密源文件
        sm4EncryptFile(encryptKey, zipPath, tempZipPath);
        
        // 4. 新的zip = (sign文件、秘钥文件、加密源文件)
    }
}

在这里插入图片描述

原文地址:https://blog.csdn.net/vbirdbest/article/details/134722233

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_30054.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注