openssl+SM2开发实例一(含源码)
一、SM2算法介绍
SM2(国密算法2) 是中国国家密码管理局(CNCA)颁布的椭圆曲线密码算法标准,属于非对称加密算法。它基于椭圆曲线离散对数问题,提供了安全可靠的数字签名、密钥交换和公钥加密等功能。SM2被设计为适用于各种场景下的密码学应用,包括数字证书、数据加密、数字签名、身份认证等。
以下是SM2算法的一些关键特点和概要介绍:
-
非对称加密算法: SM2是一种非对称加密算法,意味着它使用两个密钥:公钥和私钥。公钥用于加密数据和验证签名,而私钥用于解密数据和生成签名。
-
椭圆曲线密码学: SM2基于椭圆曲线密码学(Elliptic Curve Cryptography,ECC),使用椭圆曲线上的点运算来实现加密和签名操作。
-
安全性: SM2采用了高强度的椭圆曲线参数,保障了算法的安全性。在适当的参数选择下,SM2被认为是安全可靠的。
-
性能优越: 与传统的RSA算法相比,SM2在相同安全性水平下使用更短的密钥长度,提供了更高的性能。
-
国家标准: SM2是中国国家密码算法标准,适用于中国国内的各种密码学应用,包括政府、金融、电信等领域。
-
数字签名和密钥交换: SM2可以用于生成数字签名,验证签名的有效性,以及进行安全的密钥交换,用于建立安全的通信通道。
由于SM2是中国的国家密码标准,它在中国国内得到了广泛的应用。SM2不仅提供了高度的安全性,还具备较好的性能,适用于多种密码学场景。
二、SM2代码实例
2.1 SM2加密 / SM2解密
以下是一个简单的C++代码示例,演示了如何使用OpenSSL库进行SM2加密和解密。在这个示例中,我们将SM2加密和解密的功能拆分为两个函数:sm2_encrypt()
和 sm2_decrypt()
。
请注意,使用此示例代码前,请确保你的系统已经安装了OpenSSL库,并且链接时正确引入了OpenSSL的库文件。该示例仅供学习和参考,实际应用中,你需要根据你的需求和安全性要求进行更严格的错误处理和参数验证。
#include <openssl/evp.h>
#include <openssl/sm2.h>
#include <iostream>
#include <string>std::string sm2_encrypt(const std::string &plaintext, EVP_PKEY *pubkey) {EVP_PKEY_CTX *ctx;unsigned char *ciphertext = nullptr;size_t ciphertext_len;// 创建EVP_PKEY_CTXctx = EVP_PKEY_CTX_new(pubkey, nullptr);if (!ctx) {std::cerr << "Error creating EVP_PKEY_CTX for encryption" << std::endl;return "";}// 初始化加密操作if (EVP_PKEY_encrypt_init(ctx) <= 0) {std::cerr << "Error initializing encryption operation" << std::endl;EVP_PKEY_CTX_free(ctx);return "";}// 设置加密参数(这里可以设置一些参数,例如填充方式)// EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);// 计算加密后的长度if (EVP_PKEY_encrypt(ctx, nullptr, &ciphertext_len, reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length()) <= 0) {std::cerr << "Error computing ciphertext length" << std::endl;EVP_PKEY_CTX_free(ctx);return "";}// 分配内存并执行加密操作ciphertext = new unsigned char[ciphertext_len];if (EVP_PKEY_encrypt(ctx, ciphertext, &ciphertext_len, reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length()) <= 0) {std::cerr << "Error encrypting data" << std::endl;delete[] ciphertext;EVP_PKEY_CTX_free(ctx);return "";}// 释放资源EVP_PKEY_CTX_free(ctx);// 返回加密后的数据(Base64编码)std::string encoded_ciphertext(reinterpret_cast<char*>(ciphertext), ciphertext_len);delete[] ciphertext;return encoded_ciphertext;
}std::string sm2_decrypt(const std::string &ciphertext, EVP_PKEY *privkey) {EVP_PKEY_CTX *ctx;unsigned char *plaintext = nullptr;size_t plaintext_len;// 创建EVP_PKEY_CTXctx = EVP_PKEY_CTX_new(privkey, nullptr);if (!ctx) {std::cerr << "Error creating EVP_PKEY_CTX for decryption" << std::endl;return "";}// 初始化解密操作if (EVP_PKEY_decrypt_init(ctx) <= 0) {std::cerr << "Error initializing decryption operation" << std::endl;EVP_PKEY_CTX_free(ctx);return "";}// 计算解密后的长度if (EVP_PKEY_decrypt(ctx, nullptr, &plaintext_len, reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.length()) <= 0) {std::cerr << "Error computing plaintext length" << std::endl;EVP_PKEY_CTX_free(ctx);return "";}// 分配内存并执行解密操作plaintext = new unsigned char[plaintext_len];if (EVP_PKEY_decrypt(ctx, plaintext, &plaintext_len, reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.length()) <= 0) {std::cerr << "Error decrypting data" << std::endl;delete[] plaintext;EVP_PKEY_CTX_free(ctx);return "";}// 释放资源EVP_PKEY_CTX_free(ctx);// 返回解密后的数据std::string decrypted_plaintext(reinterpret_cast<char*>(plaintext), plaintext_len);delete[] plaintext;return decrypted_plaintext;
}int main() {EVP_PKEY *pubkey = nullptr;EVP_PKEY *privkey = nullptr;// 生成SM2密钥对if (!EVP_PKEY_keygen_SM2(&pubkey, &privkey)) {std::cerr << "Error generating SM2 key pair" << std::endl;return 1;}std::string plaintext = "Hello, SM2!";std::string ciphertext = sm2_encrypt(plaintext, pubkey);std::string decrypted_text = sm2_decrypt(ciphertext, privkey);std::cout << "Original Text: " << plaintext << std::endl;std::cout << "Encrypted Text: " << ciphertext <<std::endl;std::cout << "Decrypted Text: " << decrypted_text << std::endl;EVP_PKEY_free(pubkey);EVP_PKEY_free(privkey);return 0;
}
请确保在实际使用时对错误进行适当处理,并根据实际需求进行参数配置。此示例中,使用了OpenSSL提供的SM2密钥生成函数,加密和解密操作的结果以字符串形式输出。在实际应用中,你可能需要对加密后的数据进行Base64编码以方便传输。
2.2 SM2签名
2.2.1 SM2签名步骤
SM2签名的过程通常包括以下步骤:
-
生成密钥对: 签名方首先需要生成自己的SM2公钥和私钥。公钥用于验证签名,私钥用于生成签名。
-
计算消息的哈希值: 对待签名的消息进行哈希操作,通常使用SM3算法生成消息的摘要(哈希值)。
-
生成随机数: 生成一个随机数(称为
k
),该随机数需要满足一定的条件,以保障签名的安全性。在SM2中,k
的生成需要满足一定的随机性和不可预测性。 -
计算椭圆曲线点: 使用随机数
k
计算椭圆曲线上的点(k * G
,其中G
是椭圆曲线的基点),得到一个椭圆曲线点(x1, y1
)。 -
计算
r
值: 将椭圆曲线点的横坐标x1
对一个固定数取模,得到一个整数r
。如果r
等于0,则需要重新选择随机数k
并重新计算。 -
计算
s
值: 计算签名的另一个部分s
,公式为: s = ( ( h a s h + r ⋅ d ) / k ) m o d n s = ((hash + r \cdot d) / k) \mod n s=((hash+r⋅d)/k)modn 其中,hash
是消息的哈希值,d
是私钥,n
是椭圆曲线的阶数。 -
验证
r
和s
: 将r
和s
作为签名的两个组成部分,并与消息一起发送给验证方。验证方使用签名者的公钥、消息的哈希值、r
和s
进行验证。验证的详细步骤包括使用公钥计算椭圆曲线点,验证r
的范围和计算(s \cdot G + r \cdot PK)等。如果验证通过,则签名有效。
在SM2签名过程中,随机数k
的选择和签名的正确性非常关键,不当的随机数选择可能导致签名的不安全性。因此,在实际应用中,随机数的生成需要特别注意,通常使用专门的随机数生成库或硬件随机数生成模块来确保随机性和不可预测性。
2.2.2 SM2签名C++开发实例
2.3 SM2密钥交换
2.3.1 SM2密钥交换步骤
是的,SM2算法可以用于密钥交换。在SM2中,密钥交换是通过Diffie-Hellman密钥交换协议的椭圆曲线密码学版本来实现的。SM2密钥交换的过程基于椭圆曲线离散对数问题,该问题在椭圆曲线密码学中是困难的,因此使得SM2密钥交换具备了很高的安全性。
SM2密钥交换的流程通常包括以下步骤:
-
生成临时密钥对: 通信双方分别生成自己的临时私钥和对应的临时公钥。这两个临时密钥对仅在当前密钥交换会话中使用。
-
计算共享秘密: 通信双方分别使用自己的临时私钥和对方的临时公钥,通过椭圆曲线上的点运算计算出一个共享的秘密值。
-
生成共享密钥: 使用共享的秘密值作为密钥生成算法的输入,生成对称密钥,该密钥可以用于后续的加密和解密通信内容。
-
销毁临时密钥: 在生成共享密钥之后,临时私钥和临时公钥可以被销毁,因为它们不再需要。
SM2密钥交换的安全性建立在椭圆曲线离散对数问题的困难性上,确保了在不共享密钥的情况下,通信双方可以协商出一个共享密钥,从而实现了安全的密钥交换。
三、openssl SM2 命令操作
3.1 openssl SM2 加密
3.2 openssl sm2 解密
3.3 openssl SM2 签名
3.3 openssl SM2 验签(签名校验)
相关文章:
openssl+SM2开发实例一(含源码)
一、SM2算法介绍 SM2(国密算法2) 是中国国家密码管理局(CNCA)颁布的椭圆曲线密码算法标准,属于非对称加密算法。它基于椭圆曲线离散对数问题,提供了安全可靠的数字签名、密钥交换和公钥加密等功能。SM2被设…...

操作系统 | 编写内核
🌈个人主页:Sarapines Programmer🔥 系列专栏:《操作系统实验室》🔖少年有梦不应止于心动,更要付诸行动。 目录结构 1. 操作系统实验之编写内核 1.1 实验目的 1.2 实验内容 1.3 实验步骤 1.4 实验过程 …...
Rust逆向学习 (4)
Reverse for Struct Rust中的结构体是一个重要的内容,由于Rust中没有类的概念,因此其他编程语言中的封装、继承、多态与Rust中的表现都有较大差异。 我们使用参考书中的一个示例开始进行分析。 Struct 初始化 struct User {username: String,email: …...

uniapp vue2 vuex 持久化
1.vuex的使用 一、uniapp中有自带vuex插件,直接引用即可 二、在项目中新建文件夹store,在main.js中导入 在根目录下新建文件夹store,在此目录下新建index.js文件 index.js import Vue from vueimport Vuex from vuexVue.use(Vuex)const store new Vuex.Store(…...

【媒体邀约】媒体宣传——企业成长的催化剂
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 媒体宣传是企业成长的催化剂,它在各种方面对企业的成功和发展起到了关键作用。 1. 曝光和知名度: 媒体宣传可以将企业和其产品或服务推向广泛的受众,…...
ansible问题排查
拷贝模板时报错:AnsibleError: template error while templating string: Missing end of comment tag. 原因 shell脚本中地{#和jinja中的语法comment tag相同,而且只有一半,导致无法渲染导致。 解决 在有语法冲突的地方使用组合标签{% r…...
7天入门python系列之第四天python数据结构
第3天主要是学习Python的函数和模块 编者打算开一个python 初学主题的系列文章,用于指导想要学习python的同学。关于文章有任何疑问都可以私信作者。对于初学者想在7天内入门Python,这是一个紧凑的学习计划。但并不是不可完成的。第四天开始python 数据…...

远程电脑未连接显示器时分辨率太小的问题处理
背景:单位电脑显示器坏了,使用笔记本通过向日葵远程连接,发现分辨率只有800*600并且不能修改,网上找了好久找到了处理方法这里记录一下,主要用到的是一个虚拟显示器软件usbmmidd_v2 1)下载usbmmidd_v2 2)…...

Java 设计模式——解释器模式
目录 1.概述2.结构3.案例实现3.1.抽象表达式类3.2.终结表达式3.3.非终结表达式3.4.环境类3.5.测试 4.优缺点5.使用场景 1.概述 (1)如下图,设计一个软件用来进行加减计算。我们第一想法可能就是使用工具类,提供对应的加法和减法的…...
面试经典150题——Day37
文章目录 一、题目二、题解 一、题目 73. Set Matrix Zeroes Given an m x n integer matrix matrix, if an element is 0, set its entire row and column to 0’s. You must do it in place. Example 1: Input: matrix [[1,1,1],[1,0,1],[1,1,1]] Output: [[1,0,1],[0,…...

在 Arduino IDE 2.0 中安装 ESP32 板(Windows、Mac OS X、Linux)
有一个新的 Arduino IDE——Arduino IDE 2.0(测试版)。在本教程中,您将学习如何在 Arduino IDE 2.0 中安装 ESP32 板并将代码上传到板。本教程与 Windows、Mac OS X 和 Linux 操作系统兼容。 据 Arduino 网站称:“ Arduino IDE 2.…...
西门子S7-1200PLC混合通信编程(ModbusTcp和UDP通信)
S7-1200PLC的MODBUS-TCP通信 西门子PLC ModbusTcp通信访问网关后从站(SCL语言轮询状态机)-CSDN博客文章浏览阅读305次。西门子PLC的ModbusTcp通信在专栏已有很多文章介绍,所不同的是每个项目的通信需求都略有不同,今天我们以访问网关后的三个从站数据来举例,给出轮询的推荐…...

Hbase 迁移小结:从实践中总结出的最佳迁移策略
在数据存储和处理领域,HBase作为一种分布式、可扩展的NoSQL数据库,被广泛应用于大规模数据的存储和分析。然而,随着业务需求的变化和技术发展的进步,有时候我们需要将现有的HBase数据迁移到其他环境或存储系统。HBase数据迁移是一…...

键盘win键无法使用,win+r不生效、win键没反应、Windows键失灵解决方案(亲测可以解决)
最近几天发现自己笔记本的win键无法使用,win失灵了,但是外接键盘后则正常:。 这个问题困扰了我一周,我都以为自己的枪神坏了。 寻找了几个解决方法,网上看了好多好多稀里糊涂的办法,都是不管用的,这里给大…...

1. 深度学习——激活函数
机器学习面试题汇总与解析——激活函数 本章讲解知识点 什么是激活函数? 为什么要使用激活函数? 详细讲解激活函数 本专栏适合于Python已经入门的学生或人士,有一定的编程基础。本专栏适合于算法工程师、机器学习、图像处理求职的学生或人…...

chatglm3-6b部署及微调
chatglm3-6b部署及微调 modelscope: https://modelscope.cn/models/ZhipuAI/chatglm3-6b/filesgithub: https://github.com/THUDM/ChatGLM3镜像: ubuntu20.04-cuda11.7.1-py38-torch2.0.1-tf1.15.5-1.8.1v100 16G现存 单卡 安装 软件依赖 # 非必要无需执行 # pip install -…...
Hive 知识点八股文记录 ——(二)优化
函数 UDF:用户定义函数 UDAF:用户定义聚集函数 UDTF:用户定义表生成函数 建表优化 分区建桶 创建表时指定分区字段 PARTITIONED BY (date string)指定分桶字段和数量 CLUSTERED BY (id) INTO 10 BUCKETS插入数据按分区、分桶字段插入 …...

计算机技术专业CSIT883系统分析与项目管理介绍
文章目录 前言一、学科学习成果二、使用步骤三、最低出勤要求四、讲座时间表五、项目管理 前言 本课程介绍了信息系统开发中的技术和技术,以及与管理信息技术项目的任务相关的方法和过程。 它研究了系统分析师、客户和用户在系统开发生命周期中的互补角色。 它涵盖…...
gitlab安装地址
镜像地址: Index of /gitlab-ce/yum/el7/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror wget Index of /gitlab-ce/yum/el7/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror rpm -i gitlab-ce-15.9.1-ce.0.el7.x86_64.rpm 一直提示 &#x…...
Spark处理方法_提取文件名中的时间
需求描述 通过读取目录下的类似文件的datapath路径的文件名及文件内容,需要将读取的每一个文件的文件名日期解析出来,并作为读取当前文件内容递归读取当前文件一个df列,列名为“时间”;后面就是读一个文件,解析一下时间…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...