国密SM2算法加解密文件

对文档进行加密操作,只有经过系统解密后才能进行查看文档内容

这里使用hutool工具类提供的SM2方法,首先引入pom.xml依赖
hutool文档地址

<!--工具类-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.6.5</version>
</dependency>

生成SM2密钥对

SM2 sm2 = new SM2();
String privateKeyBase64 = sm2.getPrivateKeyBase64();
String publicKeyBase64 = sm2.getPublicKeyBase64();

FileUtils工具类,进行byte数组和文件的转换

package com.smile.common.utils.file;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import java.io.*;

/**
 * 文件处理工具类
 *
 * @author wujie
 */
@Slf4j
public class FileUtils {
  
    /**
     * 获得指定文件的byte数组
     *
     * @param filePath 文件路径
     * @return 字节数组
     */
    public static byte[] fileToByte(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * 根据byte数组,生成文件
     * @param bfile 字节数组
     * @param filePath 文件路径
     * @param fileName 文件名
     */
    public static void byteToFile(byte[] bfile, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory()) {
                dir.mkdirs();
            }
            file = new File(filePath + "\\" + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(bos);
            IOUtils.closeQuietly(fos);
        }
    }
}

EncryptionTools 加解密工具类,这里用的静态代码块,加载已存在的密钥对,不用每次都生成新的密钥

package com.smile.project.openinterface.tools.ofd;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import com.smile.common.utils.file.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 加解密工具类
 *
 * @author: WuJie
 * @version: 1.0
 **/
@Slf4j
public class EncryptionTools {

    private static SM2 SM_2 = null;

    static {
        try {
            BouncyCastleProvider BC = new BouncyCastleProvider();
            String publicKeyStr = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE6/ZmNaBRnZnisjtfxxh2r5F7MXjr2Rjf6wi5++WkUqU0APNadWN+jcZZeupwrkpOaS" +
                    "+epBpYFwaHhlMGIbUzKw==";
            String privateKeyStr = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgsTwYNqhtSjlpYDQnaKaEQbn9kVdSW3RJnFejbKTYa5KgCgYIKoEcz1UBgi2hRANCAATr9mY1oFGdmeKyO1/HGHavkXsxeOvZGN/rCLn75aRSpTQA81p1Y36Nxll66nCuSk5pL56kGlgXBoeGUwYhtTMr";
            KeyFactory keyFactory = KeyFactory.getInstance("EC", BC);
            PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKeyStr)));
            PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyStr)));
            SM_2 = SmUtil.sm2(privateKey, publicKey);
        } catch (Exception e) {
            log.info("SM2密钥初始化错误", e);
        }
    }

    /**
     * 文件加/解密
     *
     * @param source   原始文件路径
     * @param out      输出路径
     * @param fileName 输出文件名
     * @param action   行为(true为加密,false为解密)
     */
    public static void encryptionOrDecryption(String source, String out, String fileName, boolean action) {
        byte[] bytes = FileUtils.fileToByte(source);
        byte[] data;
        if (action) {
            data = SM_2.encrypt(bytes, KeyType.PublicKey);
        } else {
            data = SM_2.decrypt(bytes, KeyType.PrivateKey);
        }
        FileUtils.byteToFile(data, out, fileName);
    }

    /**
     * 测试方法
     */
    public static void main(String[] args) {
        // 加密
        encryptionOrDecryption("D:\\test\\test.pdf","D:\\test","encrypt.pdf",true);
        // 解密
        encryptionOrDecryption("D:\\test\\encrypt.pdf","D:\\test","decrypt.pdf",false);
    }
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是使用C语言实现国密SM2算法加解密代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sm3.h" #include "sm2.h" int main() { // 初始化SM2上下文 sm2_context ctx; sm2_init(&ctx); // 设置SM2公钥 unsigned char pub_key[64] = { 0x04, 0xA9, 0xF1, 0x9F, 0xC4, 0x5A, 0x2E, 0x4F, 0x5E, 0x4A, 0x12, 0x2F, 0x3D, 0x50, 0x32, 0x22, 0x62, 0x80, 0x20, 0x25, 0x61, 0x0B, 0x09, 0x06, 0x4A, 0x2F, 0x9A, 0x0D, 0x14, 0x70, 0x2C, 0x7D, 0x34, 0x7B, 0x33, 0x5B, 0x4F, 0x8E, 0x97, 0x63, 0x0E, 0x0C, 0xD7, 0x0D, 0x5B, 0x61, 0xA7, 0x32, 0x60, 0x2C, 0x17, 0x69, 0x2F, 0x00, 0x3E, 0x0F, 0x9C, 0x57, 0x0B, 0x8E, 0xF8, 0x1C, 0x00, 0x05 }; sm2_set_public_key(&ctx, pub_key); // 设置SM2私钥 unsigned char pri_key[32] = { 0x71, 0x1E, 0x5E, 0x6A, 0x39, 0x5D, 0x3D, 0x7D, 0x4F, 0x5C, 0x29, 0xC2, 0x76, 0x17, 0x38, 0x3A, 0x9B, 0xB5, 0x60, 0x4E, 0x81, 0x77, 0x1F, 0x15, 0x9D, 0x1C, 0x91, 0x21, 0x92, 0x4C, 0x63, 0x4F }; sm2_set_private_key(&ctx, pri_key); // 待加密的明文 unsigned char plain_text[32] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35 }; // 加密密文和密钥 unsigned char cipher_text[256] = {0}; unsigned char secret_key[32] = {0}; // 进行加密 sm2_encrypt(&ctx, plain_text, 32, cipher_text, secret_key); printf("cipher text:\n"); for(int i = 0; i < 128; i++) { printf("%02x", cipher_text[i]); } printf("\n"); printf("secret key:\n"); for(int i = 0; i < 32; i++) { printf("%02x", secret_key[i]); } printf("\n"); // 解密明文 unsigned char plain_text2[32] = {0}; sm2_decrypt(&ctx, cipher_text, 128, secret_key, plain_text2); printf("plain text:\n"); for(int i = 0; i < 32; i++) { printf("%02x", plain_text2[i]); } printf("\n"); return 0; } ``` 需要使用到两个库文件 `sm3.h` 和 `sm2.h`,这里不做展示。运行代码即可进行 SM2加解密操作。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值