SM2 国密算法原理与 C++跨平台实现
介绍国密 SM2 非对称加密算法的原理与 C++ 跨平台实现。SM2 基于椭圆曲线密码学,提供数字签名、公钥加密及密钥交换功能。文章详细解析了有限域运算、点运算等数学基础,并给出了完整的 C++ 头文件源码,包含 SM3 哈希、大数运算及 ECC 核心逻辑。通过单元测试验证了签名、验签、加解密流程的正确性。该实现支持 Windows 与类 Unix 系统,适用于金融、政务等需要自主可控安全技术的场景。

介绍国密 SM2 非对称加密算法的原理与 C++ 跨平台实现。SM2 基于椭圆曲线密码学,提供数字签名、公钥加密及密钥交换功能。文章详细解析了有限域运算、点运算等数学基础,并给出了完整的 C++ 头文件源码,包含 SM3 哈希、大数运算及 ECC 核心逻辑。通过单元测试验证了签名、验签、加解密流程的正确性。该实现支持 Windows 与类 Unix 系统,适用于金融、政务等需要自主可控安全技术的场景。

SM2 是我国自主研发的非对称加密算法(国密算法),于 2010 年由国密局发布,2017 年成为 ISO/IEC 国际标准。其基于椭圆曲线密码学(ECC),具备安全性高(256 位密钥强度相当于 RSA-3072 位)、运算速度快、密钥短(256 位)等优势,广泛应用于数字签名、公钥加密、密钥交换等领域,是金融、政务、物联网等场景的核心安全技术。本文从算法原理到代码实现,系统解析 SM2 的核心技术。
SM2 属于非对称加密算法,包含三个核心功能:
SM2 的安全性依赖于椭圆曲线离散对数问题:已知椭圆曲线点 P 和 Q=kP,求 k 在计算上不可行。其数学基础包括:
国密推荐曲线参数如下(十六进制):
FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFFFFFFFFFE ... FFFFFFFCFFFFFFFE ... 39D54123SM2 包含四大核心算法模块:
签名生成:
验签流程:
加密:
注:h 为余因子(通常为 1),KDF 为密钥派生函数。
解密:
基于改进的 ECDH 协议,两轮交互生成共享密钥:
| 特性 | SM2 | RSA-3072 | AES-256 |
|---|---|---|---|
| 密钥长度 | 256 位 | 3072 位 | 256 位 |
| 安全强度 | 抗量子 | 不抗量子 | 抗量子 |
| 签名速度 | 0.98ms(FPGA) | 3.2ms | N/A |
| 适用场景 | 非对称加密 | 传统非对称加密 | 对称加密 |
/*
* Copyright (c) 2025, arbboter. All rights reserved.
* File : filename.cpp
* Desc : 本文件实现 SM2 模块的核心算法
* - SM2 的签名和验签
* - SM2 的加密和解密
* Version : 1.0.0.1
* License : SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SM2_H__
#define __SM2_H__
#include <stdio.h>
#include <string.h>
#include <cstdint>
#ifdef _WIN32
#include <windows.h>
#include <bcrypt.h>
#pragma comment(lib,"bcrypt.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(status) ((NTSTATUS)(status)>=0)
#endif
#else
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#endif
// ... (省略部分宏定义以保持简洁,实际实现包含完整逻辑)
// 雅可比行列式
typedef struct {
SM2_BN X;
SM2_BN Y;
SM2_BN Z;
} SM2_JACOBIAN_POINT;
class SM2 {
public:
enum class CiphertextType { C1C3C2, C1C2C3, DER };
{
SM2_BN d;
SM2_JACOBIAN_POINT Q;
{
((d) != ) std::();
} ((d) || (d, SM2_N) >= );
Q = d * G;
(&Q, <*>(&key.public_key));
(d, key.private_key);
}
{
SM2_KEY* sk = &_key;
sm3_context ctx;
((&ctx, sk, SM2_DEFAULT_ID, (SM2_DEFAULT_ID)) != ) ;
((&ctx, src, srcLen) != ) ;
((&ctx, sk, sgn, sgnLen, rawRS) != ) ;
;
}
};
void TestSM2() {
const char* priKey = "ee9751a685f4f1ca1ef355b15b937475f90757c6ea930f04a3242901a13b94a2";
const char* pubKey = "04de16070290a70b3457fef7651c5e3be8902b5d589f3d0b80efc5f4e38a78d0e7d09b9d82acc2f31eb6314f831f0766cf644c1d5856794b9106b5f964b7b6fb5d";
const char* pMsg = "Hello, World,I love 中国.";
SM2 sm2;
if (!sm2.InitKey(priKey, pubKey)) {
std::cout << "初始化 SM2 密钥失败" << std::endl;
return;
}
std::cout << "测试数据:" << strlen(pMsg) << "," << pMsg << std::endl;
char hex[512] = {0};
char sign[128] = {0};
size_t len = sizeof(sign);
if (!sm2.SM2Sign((unsigned char*)pMsg, strlen(pMsg), (unsigned char*)sign, &len) || len == 0) {
std::cout << "生成签名失败" << std::endl;
return;
}
size_t out_len = sizeof(hex);
memset(hex, 0, sizeof(hex));
SM2::Bin2Hex(sign, len, hex, out_len);
std::cout << "生成签名成功" << std::endl;
if (!sm(( *)pMsg, (pMsg), ( *)sign, len)) {
std::cout << << std::endl;
;
}
std::cout << << out_len << << hex << std::endl;
ciphertext[] = {};
len = (ciphertext);
(!sm(( *)pMsg, (pMsg), ( *)ciphertext, &len)) {
std::cout << << std::endl;
;
}
out_len = (hex);
(hex, , (hex));
SM2::(ciphertext, len, hex, out_len);
std::cout << << out_len << << hex << std::endl;
text[] = {};
text_len = (text);
(!sm(( *)ciphertext, len, ( *)text, &text_len)) {
std::cout << << std::endl;
;
}
std::cout << << text_len << << text << std::endl;
}
测试数据:26,Hello, World,I love 中国.
生成签名成功
签名校验成功:144,3046022100945d19ee176dae52533cf0a8af25030204020131d5ac232a0ed1bdb806b2d76d022100b3cdf47895c5e3c390442f7436b0f902b2eb5c8723a70ff8479fcec0b8adae63
加密成功:270,308184022100c1a0e063e981a544f974a9aacd1dd5e193f31378ec52d79e1d4522cd8f0200a0022100de6137f68384f86735c7af776525ab42b1177574305ddeec3f2547161da3ca6a042044e04f1bd288027c43eb99c6a6b1c2071a440f27f07194e0308dfa7530841c26041a926716f58ad2d5bd0c451df6ce1bdef976c608ed03aaf2f7f21f
解密成功:26,Hello, World,I love 中国.
SM2 作为我国密码技术的核心成果,已在政务、金融、物联网等领域大规模应用。其设计融合了 ECC 的高效性与抗量子特性,结合国密标准生态(如 SM3/SM4),构建了自主可控的安全体系。未来随着抗量子算法的演进,SM2 将在后量子密码时代持续发挥关键作用。
class SM2 {
/**
* @brief 将 SM2 密文转换为十六进制字符串格式
* @param[in] C 指向 SM2 密文结构的指针
* @param[in] mode 输出格式模式:0: C1C3C2, 1: C1C2C3
* @param[out] out 输出的十六进制字符串缓冲区指针
* @param[out] outlen 输出缓冲区的实际长度
* @return 执行结果:1: 成功,-1: 失败
*/
int ciphertext_to_text(const SM2_CIPHERTEXT* C, int mode, uint8_t** out, size_t* outlen) {
// 实现细节...
return 1;
}
};

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online