rdf-file:SM2加解密

news2025/6/15 19:35:01

一:SM2简介

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

  • 生成秘钥:用于生成一对公钥和私钥。公钥:用于加密数据和验证数字签名。私钥:用于解密数据和生成数字签名。
  • 数字签名:用于生成和验证数字签名,可以独立使用。数字签名可以确保数据的完整性和身份认证,防止数据被篡改或冒充。发送方可以使用自己的私钥生成数字签名,并将签名附加在数据上发送给接收方。接收方使用发送方的公钥来验证数字签名的有效性,从而确保数据的完整性和身份认证。
  • 密钥交换:双方可以使用各自的私钥和对方的公钥来生成一个共享密钥,用于后续的对称加密通信。
  • 加密解密:发送方使用接收方的公钥进行加密,接收方使用自己的私钥进行解密。

CFCA

二:Java

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.9</version>
</dependency>

<dependency>
	<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文件、秘钥文件、加密源文件)
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1277939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv8改进 | 2023 | 给YOLOv8换个RT-DETR的检测头(重塑目标检测前沿技术)

一、本文介绍 本文给大家带来是用最新的RT-DETR模型的检测头去替换YOLOv8中的检测头。RT-DETR号称是打败YOLO的检测模型&#xff0c;其作为一种基于Transformer的检测方法&#xff0c;相较于传统的基于卷积的检测方法&#xff0c;提供了更为全面和深入的特征理解&#xff0c;将…

Safe and Practical GPU Computation in TrustZone论文阅读笔记

Safe and Practical GPU Computation in TrustZone 背景知识&#xff1a; youtube GR视频讲解链接&#xff1a;ASPLOS’22 - Session 2A - GPUReplay: A 50-KB GPU Stack for Client ML - YouTube GPU软件栈&#xff1a; 概念&#xff1a;"GPU软件栈"指的是与GPU硬件…

【代码】基于改进差分进化算法的微电网调度研究matlab

程序名称&#xff1a;基于改进差分进化算法的微电网调度研究 实现平台&#xff1a;matlab 代码简介&#xff1a;了进一步提升差分进化算法的优化性能,结合粒子群(PSO)算法的进化机制,提出一种混合多重随机变异粒子差分进化算法(DE-PSO)。所提算法不仅使用粒子群差分变异策略和…

⭐ Unity 里让 Shader 动画在 Scene 面板被持续刷新

写 Unity Shader的时候&#xff0c;只有播放状态下的 Game 面板能看到Shader 顺畅的动态效果&#xff0c;不方便。 想要带有动态效果的 Shader 在 Scene 面板持续更新动画&#xff0c;只需要打开一个开关就能让 Scene 持续刷新动画了。 感谢大家的观看&#xff0c;您的点赞和关…

nrm安装以及常用命令

做为开发者&#xff0c;我们经常会使用到淘宝镜像去安装一些包。基本上设置的都是cnpm这种。但是这一长串其实很难记住。这时&#xff0c;我们可以用nrm进行镜像的切换更为方便。 npm install -g cnpm --registryhttps://registry.npm.taobao.org 安装方法 npm install nrm …

代码随想录算法训练营第38天| 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

JAVA代码编写 动态规划&#xff08;Dynamic Programming&#xff09; 一个问题可以划分为多个子问题&#xff0c;且子问题之间有关联&#xff0c;就可以使用动态规划。 动态规划问题步骤&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式…

Linux操作系统 2.Linux基础命令

Linux基础命令&#xff0c;掌握这一套清晰的讲解就够啦&#xff01; 本篇博客给大家带来的是Linux的基础命令和vi编辑器 感谢大家收看~ 一、Linux目录结构 Linux的目录结构是一个树形结构&#xff0c;Linux只有一个根目录 / 所有文件都存在/下面 Linux路径的描述方式 Linux系…

通过查看ThreadLocal的源码进行简单理解

目录 为什么要使用ThreadLocal&#xff1f; 简单案例 ThreadLocal源码分析 断点跟踪 为什么要使用ThreadLocal 在多线程下&#xff0c;如果同时修改公共变量可能会存在线程安全问题&#xff0c;JDK虽然提供了同步锁与Lock等方法给公共访问资源加锁&#xff0c;但在高并发…

OpenCV-Python:计算机视觉框架

1.背景 俗话说“工欲善其事必先利其器”&#xff0c;想要学好计算机视觉&#xff0c;需要借助于相关的计算机视觉库&#xff0c;这样在进行学习的时候可以达到事半功倍的效果。 2.早期计算机视觉框架概述 Matlab的最早历史可以追溯到1970年&#xff0c;开始是作为数据处理工…

YUVRGB

一、直观感受 根据上面的图片&#xff0c;不难看出&#xff1a; RGB的每个分量&#xff0c;是对当前颜色的一个亮度值Y分量对呈现出清晰的图像有着很大的贡献Cb、Cr分量的内容不太容易识别清楚YUV将亮度信息&#xff08;Y&#xff09;与色度信息&#xff08;UV&#xff09;分离…

最多不一定最好,只有适合的才是最好的!电脑的内存多大才是合理的

RAM&#xff0c;或称随机存取存储器&#xff0c;是最好的笔记本电脑和最好的电脑最重要的组成部分之一。硬盘驱动器&#xff08;HDD&#xff09;或固态驱动器&#xff08;SSD&#xff09;存储可以被视为电脑的长期内存&#xff0c;内存是其短期内存。内存可以跟踪后台运行的应用…

P6 链表 插入数据节点 尾插法指定节点插入

目录 前言 ​编辑 01 链表指定节点后插入数据&#xff08;根据节点号插入&#xff09; 测试代码 02 链表指定节点后插入数据&#xff08;根据节点的数据插入&#xff09; 尾插法的代码 前言 …

for循环定义域问题

记录一个偶然发现的问题&#xff0c;代码如下 int main(int argc, char *argv[], char *envp[]){for(int i 1; i < 10; i);printf("%d",i); return 0; } 可以看到for循环后加了一个分号&#xff0c;按理说应该报变量i未定义的错误&#xff0c;但此时在编译器中…

RCE绕过

1.[SCTF 2021]rceme 总结下获取disabled_funciton的方式 1.phpinfo() 2.var_dump(ini_get(“disable_functions”)); 3.var_dump(get_cfg_var(“disable_functions”)); 其他的 var_dump(get_cfg_var(“open_basedir”)); var_dump(ini_get_all()); <?php if(isset($_POS…

使用coco数据集进行语义分割(1):数据预处理,制作ground truth

如何coco数据集进行目标检测的介绍已经有很多了&#xff0c;但是关于语义分割几乎没有。本文旨在说明如何处理 stuff_train2017.json stuff_val2017.json panoptic_train2017.json panoptic_val2017.json&#xff0c;将上面那些json中的dict转化为图片的label mask&am…

C++入门篇第十篇----继承

前言&#xff1a; 本篇我们将开始讲解C的继承&#xff0c;我想要说的是&#xff0c;C的主体基本就是围绕类和对象展开的&#xff0c;继承也是以类和对象为主体&#xff0c;可以说&#xff0c;C相较于C优化的地方就在于它对于结构体的使用方法的高度扩展和适用于更多实际的场景…

ffmpeg 任意文件读取漏洞/SSRF漏洞 (CVE-2016-1897/CVE-2016-1898)

漏洞描述 影响范围 FFmpeg 2.8.x < 2.8.5FFmpeg 2.7.x < 2.7.5FFmpeg 2.6.x < 2.6.7FFmpeg 2.5.x < 2.5.10 漏洞环境及利用 搭建docker环境 访问8080端口看到上传界面 由于vulhub并没有讲述该漏洞如何复现&#xff0c;我们需要进入环境查看源码 <?php if(!…

电大搜题:开启你的学习新篇章

广西开放大学&#xff0c;作为一所具有悠久历史和丰富经验的广播电视大学&#xff0c;在教育领域享有盛誉。如今&#xff0c;随着科技的迅猛发展&#xff0c;广西开放大学推出了电大搜题微信公众号&#xff0c;为广大学子提供了一个便捷、高效的学习工具。 电大搜题微信公众号…

2_企业级Nginx使用-day1

#企业级Nginx使用-day1 学习目标和内容 1、能够了解Nginx的信号参数 2、能够进行平滑升级Nginx 3、能够配置server虚拟机 4、能够部署上线项目到LNMP架构中 5、能够了解Nginx的常用官方模块 6、能够了解日志相关使用 一、重装和升级 在实际业务场景中&#xff0c;需要使用软件…

linux之buildroot(2)配置toolchain

Linux之buildroot(2)配置toolchain Author&#xff1a;Onceday Date&#xff1a;2023年11月27日 漫漫长路&#xff0c;才刚刚开始… 全系列文章请查看专栏: buildroot编译框架_Once_day的博客-CSDN博客 参考文档&#xff1a; Buildroot - Making Embedded Linux Easy 文章…