【密碼學實戰】國密SM2算法介紹及加解密/簽名代碼實現示例

引言

在信息安全領域,密碼算法是數據保護的核心基石。2010 年,中國國家密碼管理局發布了 SM2 橢圓曲線公鑰密碼算法,作為國產密碼標準的核心成員,它憑借高效安全的特性,逐步替代 RSA 等國際算法,廣泛應用于金融、政務、物聯網等關鍵領域。SM2 的誕生不僅是技術突破,更是國家信息安全戰略的重要布局。其基于橢圓曲線密碼學(ECC)的設計,在同等安全強度下,密鑰長度僅為 RSA 的 1/10,運算效率提升數倍。SM2 已成為 ISO/IEC 國際標準,并深度融入國產密碼生態體系,為構建安全可靠的網絡安全架構提供了堅實支撐。

一、核心功能

SM2算法提供了三大核心功能:非對稱加密、數字簽名和密鑰交換,其設計目標是通過橢圓曲線的數學特性,實現高效且安全的數據保護。

1. 密鑰生成

SM2的密鑰對由私鑰和公鑰組成:

  • 私鑰:一個256位的隨機整數?dd,滿足?1≤d≤n?11≤d≤n?1,其中?nn?是橢圓曲線基點?GG?的階。
  • 公鑰:通過橢圓曲線點乘運算生成,即?P=[d]GP=[d]G,結果是一個橢圓曲線上的點?(x,y)(x,y),通常以非壓縮格式?04∣∣x∣∣y04∣∣x∣∣y?存儲(65字節)。

2. 加密與解密

SM2的加密過程采用混合加密體系,結合非對稱加密和對稱加密的優點:

  • 加密:生成密文?C=C1∣∣C2∣∣C3C=C1∣∣C2∣∣C3,其中:
    • C1C1:隨機數?kk?與基點?GG?的點乘結果?[k]G[k]G,用于生成臨時共享密鑰。
    • C2C2:明文?MM?通過對稱加密(如SM3派生的密鑰流)生成的密文。
    • C3C3:通過SM3哈希算法計算的完整性校驗值?Hash(x2∣∣M∣∣y2)Hash(x2∣∣M∣∣y2),防止數據篡改。
  • 解密:接收方通過私鑰?dd?計算共享密鑰,解密?C2C2?并驗證?C3C3。

3. 數字簽名與驗證

SM2的簽名機制基于SM3哈希算法和橢圓曲線數學特性:

  • 簽名生成:私鑰?dd?和隨機數?kk?生成簽名?(r,s)(r,s),其中?rr?是?[k]G[k]G?的?xx?坐標模?nn,ss?是?(1+d)?1?(k?r?d)mod??n(1+d)?1?(k?r?d)modn。
  • 簽名驗證:通過公鑰?PP?和簽名參數?(r,s)(r,s)?驗證等式?u1?G+u2?Pu1??G+u2??P?的?xx?坐標是否等于?rr。

4. 密鑰交換

SM2通過橢圓曲線Diffie-Hellman(ECDH)變體實現密鑰交換:

  • 客戶端生成臨時密鑰對?(dC,QC)(dC?,QC?),服務端使用證書中的公鑰?QSQS??與?dCdC??計算共享密鑰,雙方通過KDF生成會話密鑰。

二、數學原理

SM2算法的安全性建立在**橢圓曲線離散對數問題(ECDLP)**的困難性上。其數學基礎包括以下核心參數:

1. 橢圓曲線方程

SM2采用素數域上的橢圓曲線,方程為:

y2=x3+ax+bmod??py2=x3+ax+bmodp

其中:

  • pp:256位大素數,定義有限域?FpFp?。
  • aa、bb:曲線系數,滿足?4a3+27b2≠0mod??p4a3+27b2=0modp。
  • GG:基點,是曲線上的一個固定點,作為生成元。
  • nn:基點?GG?的階,為大素數。

2. 密鑰生成與點乘運算

  • 私鑰生成:隨機選擇?d∈[1,n?1]d∈[1,n?1]。
  • 公鑰生成:計算?P=[d]GP=[d]G,即基點?GG?與私鑰?dd?的點乘結果。

3. 安全性分析

SM2的256位密鑰長度提供約128比特的安全強度,相當于3072位RSA的安全水平。其優勢在于:

  • 密鑰長度短:運算效率高,適合資源受限設備(如智能卡、嵌入式系統)。
  • 抗攻擊性強:基于ECDLP問題,目前無多項式時間算法可破解。

三、加解密及數字簽名開源代碼實現示例

?1. SM2加解密代碼示例:

/** This file is part of the openHiTLS project.** openHiTLS is licensed under the Mulan PSL v2.* You can use this software according to the terms and conditions of the Mulan PSL v2.* You may obtain a copy of Mulan PSL v2 at:**     http://license.coscl.org.cn/MulanPSL2** THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.* See the Mulan PSL v2 for more details.*/#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "crypt_eal_pkey.h" // Header file of the interfaces for asymmetric encryption and decryption.
#include "bsl_sal.h"
#include "bsl_err.h"
#include "crypt_algid.h"
#include "crypt_errno.h"
#include "crypt_eal_rand.h"
#include "crypt_eal_init.h"
#include "crypt_types.h"void *StdMalloc(uint32_t len) {return malloc((uint32_t)len);
}
void PrintLastError(void) {const char *file = NULL;uint32_t line = 0;BSL_ERR_GetLastErrorFileLine(&file, &line);printf("failed at file %s at line %d\n", file, line);
}int main(void) {int32_t ret;BSL_ERR_Init();  // Initialize the error code module./*** Before calling the algorithm APIs,* call the BSL_SAL_CallBack_Ctrl function to register the malloc and free functions.* Execute this step only once. If the memory allocation ability of Linux is available,* the two functions can be registered using Linux by default.*/BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc);BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free);ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER);if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);PrintLastError();goto EXIT;}CRYPT_EAL_PkeyCtx *pkey = NULL;pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2);if (pkey == NULL) {PrintLastError();goto EXIT;}// Initialize the random number.ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL);if (ret != CRYPT_SUCCESS) {printf("RandInit: error code is %x\n", ret);PrintLastError();goto EXIT;}// Generate a key pair.ret = CRYPT_EAL_PkeyGen(pkey);if (ret != CRYPT_SUCCESS) {printf("CRYPT_EAL_PkeyGen: error code is %x\n", ret);PrintLastError();goto EXIT;}// Data to be encrypted.char *data = "test enc data";uint32_t dataLen = 12;uint8_t ecrypt[125] = {0};uint32_t ecryptLen = 125;uint8_t dcrypt[125] = {0};uint32_t dcryptLen = 125;// Encrypt data.ret = CRYPT_EAL_PkeyEncrypt(pkey, data, dataLen, ecrypt, &ecryptLen);if (ret != CRYPT_SUCCESS) {printf("CRYPT_EAL_PkeyEncrypt: error code is %x\n", ret);PrintLastError();goto EXIT;}// Decrypt data.ret = CRYPT_EAL_PkeyDecrypt(pkey, ecrypt, ecryptLen, dcrypt, &dcryptLen);if (ret != CRYPT_SUCCESS) {printf("CRYPT_EAL_PkeyDecrypt: error code is %x\n", ret);PrintLastError();goto EXIT;}if (memcmp(dcrypt, data, dataLen) == 0) {printf("encrypt and decrypt success\n");} else {ret = -1;}
EXIT:// Release the context memory.CRYPT_EAL_PkeyFreeCtx(pkey);CRYPT_EAL_RandDeinit();BSL_ERR_DeInit();return ret;
}

2. SM2簽名代碼示例:

/** This file is part of the openHiTLS project.** openHiTLS is licensed under the Mulan PSL v2.* You can use this software according to the terms and conditions of the Mulan PSL v2.* You may obtain a copy of Mulan PSL v2 at:**     http://license.coscl.org.cn/MulanPSL2** THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.* See the Mulan PSL v2 for more details.*/#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "crypt_eal_pkey.h" // Header file for signature verification.
#include "bsl_sal.h"
#include "bsl_err.h"
#include "crypt_algid.h"
#include "crypt_errno.h"
#include "crypt_eal_rand.h"
#include "crypt_eal_init.h"void *StdMalloc(uint32_t len) {return malloc((size_t)len);
}void PrintLastError(void) {const char *file = NULL;uint32_t line = 0;BSL_ERR_GetLastErrorFileLine(&file, &line);// Obtain the name and number of lines of the error file.printf("failed at file %s at line %d\n", file, line);
}int main(void)
{int ret;uint8_t userId[32] = {0};uint8_t key[32] = {0};uint8_t msg[32] = {0};uint8_t signBuf[100] = {0};uint32_t signLen = sizeof(signBuf);CRYPT_EAL_PkeyPrv prv = {0};CRYPT_EAL_PkeyPub pub = {0};CRYPT_EAL_PkeyCtx *ctx = NULL;BSL_ERR_Init(); // Initialize the error code module./*** Before calling the algorithm APIs,* call the BSL_SAL_CallBack_Ctrl function to register the malloc and free functions.* Execute this step only once. If the memory allocation ability of Linux is available,* the two functions can be registered using Linux by default.*/BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc);BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free);ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER);if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);goto EXIT;}ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2);if (ctx == NULL) {goto EXIT;}// Set a user ID.ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId));if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);PrintLastError();goto EXIT;}// Initialize the random number.ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL);if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);PrintLastError();goto EXIT;}// Generate a key pair.ret = CRYPT_EAL_PkeyGen(ctx);if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);PrintLastError();goto EXIT;}// Sign.ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen);if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);PrintLastError();goto EXIT;}// Verify the signature.ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen);if (ret != CRYPT_SUCCESS) {printf("error code is %x\n", ret);PrintLastError();goto EXIT;}printf("pass \n");EXIT:// Release the context memory.CRYPT_EAL_PkeyFreeCtx(ctx);CRYPT_EAL_RandDeinit();BSL_ERR_DeInit();return ret;
}

【免費下載openHiTLS開源代碼】

?openHiTLS旨在打造算法先進、性能卓越、高效敏捷、安全可靠的密碼套件,通過輕量級、可剪裁的軟件技術架構滿足各行業不同場景的多樣化要求,讓密碼技術應用更簡單,同時探索后量子等先進算法創新實踐,構建密碼前沿技術底座!
?項目地址:https://gitcode.com/openHiTLS/openhitls

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918919.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918919.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918919.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QT開發中如何加載第三方dll文件

文章目錄&#x1f527; 一、隱式加載&#xff08;靜態鏈接&#xff09;操作步驟&#xff1a;?? 二、顯式加載&#xff08;動態鏈接&#xff0c;推薦使用QLibrary&#xff09;操作步驟&#xff1a;&#x1f4bb; 三、直接調用Windows API&#xff08;僅Windows&#xff09;??…

后端學習資料 持續更新中

數據庫&#xff1a; 該網址包含&#xff1a;圖解MySql&#xff0c; 看明白誰也問不倒你~ 圖解計算機網絡、操作系統、計算機組成、MySQL、Redis&#xff0c;讓天下沒有難懂的八股文&#xff01;https://xiaolincoding.com/

《嵌入式Linux應用編程(六):并發編程基礎:多進程exec函數族及多線程基礎》

一、exec函數族在一個進程里面執行另一個文件本質&#xff1a;將文本區的指令代碼替換成exec要執行的指令#include <unistd.h>參數&#xff1a;path:要執行的可執行文件的路徑和名稱arg:執行該可執行文件時需要傳遞的參數NULL&#xff1a;參數傳遞結束標志 返回值&#x…

【121頁PPT】智慧方案智慧綜合體智能化設計方案(附下載方式)

篇幅所限&#xff0c;本文只提供部分資料內容&#xff0c;完整資料請看下面鏈接 https://download.csdn.net/download/2501_92808859/91654007 資料解讀&#xff1a;【121頁PPT】智慧方案智慧綜合體智能化設計方案 詳細資料請看本解讀文章的最后內容 一、項目概述與智能化總…

Linux網絡基礎(一)

目錄 計算機網絡背景 網絡發展 初識 "協議" 網絡協議初識 協議分層 軟件分層的好處 打電話例子 OSI七層模型 TCP/IP五層(或四層)模型 參考資料 再識協議 為什么要有 TCP/IP 協議&#xff1f; 什么是 TCP/IP 協議&#xff1f; TCP/IP 協議與操作系統的關系(宏觀上&…

MySQL多表查詢案例

多表查詢本文介紹了多表查詢中的表關系概念和操作方法。主要內容包括&#xff1a;1.三種表關系類型&#xff08;一對多、多對多、一對一&#xff09;及其實現方式&#xff1b;2.多表查詢的四種連接方式&#xff08;內連接、左外連接、右外連接、自連接&#xff09;及語法&#…

Dify 從入門到精通(第 36/100 篇):Dify 的插件生態擴展

Dify 從入門到精通&#xff08;第 36/100 篇&#xff09;&#xff1a;Dify 的插件生態擴展 Dify 入門到精通系列文章目錄 第一篇《Dify 究竟是什么&#xff1f;真能開啟低代碼 AI 應用開發的未來&#xff1f;》介紹了 Dify 的定位與優勢第二篇《Dify 的核心組件&#xff1a;從…

【已解決】在Spring Boot工程中,若未識別到resources/db文件夾下的SQL文件

在Spring Boot工程中&#xff0c;若未識別到resources/db文件夾下的SQL文件&#xff0c;通常與資源路徑配置、構建工具設置或代碼加載方式有關。以下是逐步排查和解決方案&#xff1a;??1. 確認SQL文件存放路徑??Spring Boot默認從類路徑&#xff08;classpath:&#xff09…

【Java】網絡編程(4)

1. 再談 UDP 報文長度&#xff1a;也是 2 個字節&#xff0c; 0 - 65535&#xff0c;也就是 64 kb。這表示一個 UDP 數據包一次最多只能傳輸 64 kb 的數據校驗和&#xff1a;驗證數據是否在傳輸過程中發生修改。數據在傳輸過程中可能受到信號干擾&#xff0c;發生 “比特翻轉”…

QT(事件)

一、事件前言事件是QT的三大機制之一&#xff0c;一定程度上信號和槽也屬于事件的一種 QT中的事件指哪些&#xff1a;窗口關閉&#xff0c;窗口顯示&#xff0c;敲擊鍵盤&#xff0c;點擊鼠標左鍵、鼠標右鍵、鼠標滾輪&#xff0c;文件拖放等等1、事件循環QT中的所有事件&#…

基于 Vue2+Quill 的富文本編輯器全方案:功能實現與樣式優化

在 Web 開發中&#xff0c;富文本編輯器是內容管理系統、博客平臺等應用的核心組件。本文將詳細介紹如何基于 Vue 和 Quill 構建一個功能完善、樣式精美的富文本編輯器&#xff0c;重點解決字體字號選項冗長、樣式不美觀及功能完整性問題&#xff0c;提供可直接部署使用的完整方…

C#內嵌字符串格式化輸出

內嵌字符串格式輸出 double speedOfLight 299792.458;System.Globalization.CultureInfo.CurrentCulture System.Globalization.CultureInfo.GetCultureInfo("nl-NL"); string messageInCurrentCulture $"The speed of light is {speedOfLight:N3} km/s.&quo…

ThreeJS程序化生成城市大場景底座(性能測試)

一、簡介基于矢量geojson數據構建建筑、植被、道路等&#xff0c;實現城市場景底座。涉及渲染的性能優化無非就是眾所周知的那些事兒。視錐剔除、mesh合并、減少draw call、四叉樹、八叉樹、數據壓縮、WebWorker、著色器優化等。下面是對東莞市數十萬建筑以及海量3D樹的渲染測試…

?電風扇離線語音芯片方案設計與應用場景:基于 8 腳 MCU 與 WTK6900P 的創新融合

?電風扇離線語音芯片方案設計與應用場景&#xff1a;基于 8 腳 MCU 與 WTK6900P 的創新融合一、引言在智能家居領域蓬勃發展的當下&#xff0c;用戶對于家電產品的智能化和便捷性需求日益增長。傳統的電風扇控制方式&#xff0c;如按鍵操作或遙控器控制&#xff0c;在某些場景…

(第四篇)spring cloud之Consul注冊中心

目錄 一、介紹 二、安裝 三、整合代碼使用 1、創建服務提供者8006 2、創建服務消費者80 3、Eureka、zookeeper和consul的異同點 一、介紹 Consul 是一套開源的分布式服務發現和配置管理系統&#xff0c;由 HashiCorp 公司用 Go 語言開發。它提供了微服務系統中的服務治理…

NAT 和 PNAT

核心概念與背景 IPv4 地址枯竭&#xff1a; IPv4 地址空間有限&#xff08;約 42.9 億個&#xff09;&#xff0c;早已分配殆盡。NAT/PNAT 是緩解此問題的最重要、最廣泛部署的技術。私有 IP 地址空間&#xff1a; IANA 保留了三個 IPv4 地址段專供私有網絡內部使用&#xff08…

windows系統創建FTP服務

一丶開啟FTP功能 控制面板->程序與功能->啟用或關閉windows功能->Internet Information Services->勾選FTP服務器二丶創建FTP服務 1丶控制面板->windows工具->Internet Information Services (IIS) 管理器2丶網站->添加FTP站點->輸入對應內容3丶點擊新…

DeepSeek補全IBM MQ 9.4 REST API 執行命令的PPT

DeepSeek補全了我在網上找到的PPT的一頁內容&#xff0c;幫了大忙了。人機協同&#xff0c;人工智能可以協助人更好的做事。下面的內容是講解IBM MQ REST API 執行IBM MQ命令的PPT: MQSC for REST Tailored RESTful support for individual MQ objects and actions are in the …

【swift】SwiftUI動畫卡頓全解:GeometryReader濫用檢測與Canvas繪制替代方案

SwiftUI動畫卡頓全解&#xff1a;GeometryReader濫用檢測與Canvas繪制替代方案一、GeometryReader的性能陷阱深度解析1. 布局計算機制2. 動畫中的災難性表現二、GeometryReader濫用檢測系統1. 靜態代碼分析器2. 運行時性能監控三、Canvas繪制優化方案1. 基礎Canvas實現2. 性能優…

悄悄話、合唱層次感:聲網空間音頻解鎖語聊新玩法

作為語聊房主播&#xff0c;我曾覺得線上相聚差點意思。多人開麥時聲音混雜&#xff0c;互動缺真實感&#xff0c;觀眾留不住&#xff0c;自己播著也沒勁。直到平臺接入聲網空間音頻&#xff0c;一切改觀&#xff0c;觀眾說像在真實房間聊天&#xff0c;留存率漲 35%&#xff0…