[密碼學實戰]Java實現國密(SM2)密鑰協商詳解:原理、代碼與實踐


一、代碼運行結果

在這里插入圖片描述

二、國密算法與密鑰協商背景

2.1 什么是國密算法?

國密算法是由中國國家密碼管理局制定的商用密碼標準,包括:

  • SM2:橢圓曲線公鑰密碼算法(非對稱加密/簽名/密鑰協商)
  • SM3:密碼雜湊算法(哈希)
  • SM4:分組密碼算法(對稱加密)

2.2 密鑰協商的意義

在安全通信中,雙方需要在不安全的信道上協商出相同的會話密鑰,用于后續對稱加密。SM2密鑰協商協議解決了以下問題:

  • 避免預先共享密鑰
  • 抵抗中間人攻擊
  • 支持雙向身份認證

三、SM2密鑰協商原理詳解

3.1 核心流程(基于ECMQV協議)

步驟角色A(發起方)角色B(響應方)
1生成臨時密鑰對 (rA, RA)生成臨時密鑰對 (rB, RB)
2發送RA給B發送RB給A
3使用雙方公鑰和臨時公鑰計算共享密鑰使用雙方公鑰和臨時公鑰計算共享密鑰

3.2 關鍵公式

共享密鑰 = KDF( x_U \cdot (d_A + r_A \cdot s_A) \cdot (P_B + [s_B] \cdot R_B) )
  • x_U:橢圓曲線點坐標的x分量
  • d_A:A方私鑰
  • r_A:A方臨時私鑰
  • s_A/s_B:靜態公鑰派生參數

四、Java實現環境準備

4.1 依賴配置

<!-- Bouncy Castle國密支持 -->
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.65</version>
</dependency>

4.2 初始化安全提供者

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;public class SM2KeyExchange {static {Security.addProvider(new BouncyCastleProvider()); // 添加BC提供者}
}

五、Java核心代碼實現(含詳細注釋)

5.1 密鑰對生成工具類

 /*** 生成SM2靜態密鑰對*/public static KeyPair generateStaticKeyPair() throws Exception {ECParameterSpec sm2Spec = ECNamedCurveTable.getParameterSpec("sm2p256v1");KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");kpg.initialize(sm2Spec, new SecureRandom());return kpg.generateKeyPair();}/*** 生成臨時密鑰對(用于密鑰協商)*/public static KeyPair generateEphemeralKeyPair() throws Exception {return generateStaticKeyPair();}

5.2 密鑰協商核心邏輯

/*** 發起方計算共享密鑰* @param staticKeyPair       己方靜態密鑰對* @param ephemeralKeyPair   己方臨時密鑰對* @param otherStaticPub     對方靜態公鑰* @param otherEphemeralPub 對方臨時公鑰* @return 共享密鑰字節數組*/public static byte[] initiatorAgreement(KeyPair staticKeyPair,KeyPair ephemeralKeyPair,PublicKey otherStaticPub,PublicKey otherEphemeralPub) {ECMQVBasicAgreement agreement = new ECMQVBasicAgreement();// 構建本地私鑰參數(包含靜態私鑰、臨時私鑰和臨時公鑰)MQVPrivateParameters localParams = new MQVPrivateParameters((ECPrivateKeyParameters) convertToBC(staticKeyPair.getPrivate()),(ECPrivateKeyParameters) convertToBC(ephemeralKeyPair.getPrivate()),(ECPublicKeyParameters) convertToBC(ephemeralKeyPair.getPublic()));// 初始化時僅傳遞本地私鑰參數agreement.init(localParams); // 構建遠端公鑰參數(對方靜態公鑰 + 臨時公鑰)MQVPublicParameters remoteParams = new MQVPublicParameters((ECPublicKeyParameters) convertToBC(otherStaticPub),(ECPublicKeyParameters) convertToBC(otherEphemeralPub));// 計算協商結果時傳遞遠端公鑰參數BigInteger sharedSecret = agreement.calculateAgreement(remoteParams); return sharedSecret.toByteArray();}

5.3 密鑰派生函數(KDF)示例

import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.generators.KDF2BytesGenerator;/*** 國密KDF實現*/
public class SM2KDF {/*** 使用SM3進行密鑰派生* @param sharedSecret 原始共享密鑰* @param keyLength 目標密鑰長度(單位:字節)*/public static byte[] kdf(byte[] sharedSecret, int keyLength) {Digest digest = new SM3Digest();KDF2BytesGenerator kdf = new KDF2BytesGenerator(digest);kdf.init(new KDFParameters(sharedSecret, new byte[0])); // 無鹽值byte[] derivedKey = new byte[keyLength];kdf.generateBytes(derivedKey, 0, keyLength);return derivedKey;}
}

六、應用場景分析

6.1 典型應用場景

場景說明
物聯網安全通信設備與云端協商會話密鑰,用于加密傳感器數據
移動支付POS終端與支付網關建立安全通道
視頻會議加密參與方動態協商密鑰,保證會議內容機密性

6.2 協議優勢

  1. 前向安全性:臨時密鑰對使用后立即銷毀,即使長期密鑰泄露,歷史會話仍安全
  2. 雙向認證:可結合數字證書驗證雙方身份
  3. 國密合規:滿足等保2.0和金融行業安全要求

七、注意事項與優化建議

7.1 安全注意事項

  • 隨機數質量:密鑰協商中的臨時密鑰必須使用密碼學安全隨機數生成器
  • 密鑰派生:必須使用KDF(如SM3)處理原始共享密鑰,避免直接使用
  • 密鑰生命周期:協商出的會話密鑰應定期更新(建議不超過24小時)

7.2 性能優化技巧

  • 預生成臨時密鑰:在高并發場景中預生成臨時密鑰池
  • 硬件加速:使用支持SM2的HSM(硬件安全模塊)提升計算速度
  • 緩存復用:在短連接場景中復用會話密鑰(需權衡安全性)

八、完整測試案例

 public static void main(String[] args) throws Exception {Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());// 1. 生成雙方靜態密鑰對KeyPair aliceStaticKey = generateStaticKeyPair();KeyPair bobStaticKey = generateStaticKeyPair();// 2. 生成臨時密鑰對KeyPair aliceEphemeralKey = generateEphemeralKeyPair();KeyPair bobEphemeralKey = generateEphemeralKeyPair();// 3. Alice作為發起方計算共享密鑰byte[] aliceSharedSecret = SM2KeyAgreement.initiatorAgreement(aliceStaticKey,aliceEphemeralKey,bobStaticKey.getPublic(),bobEphemeralKey.getPublic());// 4. Bob作為發起方計算共享密鑰(對稱操作)byte[] bobSharedSecret = SM2KeyAgreement.initiatorAgreement(bobStaticKey,bobEphemeralKey,aliceStaticKey.getPublic(),aliceEphemeralKey.getPublic());// 5. 驗證密鑰一致性System.out.println("密鑰協商是否成功: " +Arrays.equals(aliceSharedSecret, bobSharedSecret));// 6. 派生實際加密密鑰(生成128位SM4密鑰)byte[] sm4Key = Arrays.copyOfRange(aliceSharedSecret, 0, 16);System.out.println("SM4密鑰: " + Hex.toHexString(sm4Key));

九、總結

本文完整實現了基于SM2國密算法的密鑰協商協議,包含以下核心內容:

  1. 原理剖析:基于ECMQV協議的密鑰交換流程
  2. 代碼實現:靜態/臨時密鑰生成、協商計算、KDF派生
  3. 場景分析:物聯網、金融支付等典型應用場景

注意事項:生產環境請結合證書體系實現身份認證。

希望這篇文章對你有所幫助!如果覺得不錯,別忘了點贊收藏哦!

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

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

相關文章

動漫短劇開發公司,短劇小程序搭建快速上線

在當今快節奏的生活里&#xff0c;人們的娛樂方式愈發多元&#xff0c;而動漫短劇作為新興娛樂形式&#xff0c;正以獨特魅力迅速崛起&#xff0c;成為娛樂市場的耀眼新星。近年來&#xff0c;動漫短劇市場呈爆發式增長&#xff0c;吸引眾多創作者與觀眾目光。 從市場規模來看…

第四十五:創建一個vue 的程序

html <div id"app">{{ msg }}<h2>{{ web.title }}</h2><h3>{{ web.url }}</h3> </div> js /*<div id"app"></div> 指定一個 id 為 app 的 div 元素{{ }} 插值表達式, 可以將 Vue 實例中定義的數據在視圖…

docer swarm集群部署springboot項目

1.準備兩臺服務器&#xff0c;安裝好docker、docker-compose 因為用到了docker倉庫&#xff0c;安裝harbor,可以從github下載離線安裝包 2. 我這邊用到了gitlab-ci,整體流程也都差不多 1&#xff09;打包mvn clean install 2&#xff09;打鏡像 docker-compose -f docker-compo…

Python測試框架Pytest的參數化

上篇博文介紹過&#xff0c;Pytest是目前比較成熟功能齊全的測試框架&#xff0c;使用率肯定也不斷攀升。 在實際工作中&#xff0c;許多測試用例都是類似的重復&#xff0c;一個個寫最后代碼會顯得很冗余。這里&#xff0c;我們來了解一下pytest.mark.parametrize裝飾器&…

開發博客系統

前言 準備工作 數據庫表分為實體表和關系表 第一&#xff0c;建數據庫表 然后導入前端頁面 創建公共模塊 就是統一返回值&#xff0c;異常那些東西 自己造一個自定義異常 普通類 mapper 獲取全部博客 我們只需要返回id&#xff0c;title&#xff0c;content&#xff0c;us…

【Spring Boot 應用開發】-05 命令行參數

Spring Boot 常用命令行參數 Spring Boot 支持多種命令行參數&#xff0c;這些參數可以在啟動應用時通過命令行直接傳遞。以下是一些常用的命令行參數及其詳細說明&#xff1a; 1. 基本配置參數 --server.port端口號 指定應用程序運行的HTTP端口&#xff0c;默認為8080。 jav…

20250304學習記錄

第一部分&#xff0c;先來了解一下各種論文期刊吧&#xff0c;畢竟也是這把歲數了&#xff0c;還什么都不懂呢 國際期刊&#xff1a; EI收集的主要有兩種&#xff0c; JA&#xff1a;EI源刊 CA&#xff1a;EI會議 CPCI也叫 ISTP 常說的SCI分區是指&#xff0c;JCR的一區、…

2024 年 MySQL 8.0.40 安裝配置、Workbench漢化教程最簡易(保姆級)

首先到官網上下載安裝包&#xff1a;http://www.mysql.com 點擊下載&#xff0c;拉到最下面&#xff0c;點擊社區版下載 windows用戶點擊下面適用于windows的安裝程序 點擊下載&#xff0c;網絡條件好可以點第一個&#xff0c;怕下著下著斷了點第二個離線下載 雙擊下載好的安裝…

網絡安全檢查漏洞內容回復 網絡安全的漏洞

網絡安全的核心目標是保障業務系統的可持續性和數據的安全性&#xff0c;而這兩點的主要威脅來自于蠕蟲的暴發、黑客的攻擊、拒絕服務攻擊、木馬。蠕蟲、黑客攻擊問題都和漏洞緊密聯系在一起&#xff0c;一旦有重大安全漏洞出現&#xff0c;整個互聯網就會面臨一次重大挑戰。雖…

汽車智能鑰匙中PKE低頻天線的作用

PKE&#xff08;Passive Keyless Entry&#xff09;即被動式無鑰匙進入系統&#xff0c;汽車智能鑰匙中PKE低頻天線在現代汽車的智能功能和安全保障方面發揮著關鍵作用&#xff0c;以下是其具體作用&#xff1a; 信號交互與身份認證 低頻信號接收&#xff1a;當車主靠近車輛時…

uiautomatorviewer定位元素報Unexpected ... UI hierarchy

發現問題 借鑒博客 Unexpected error while obtaining UI hierarchy android app UI自動化-元素定位輔助工具 Unexpected error while obtaining UI hierarchy&#xff1a;使用uiautomatorviewer定位元素報錯 最近在做安卓自動化,安卓自動化主要工作之一就是獲取UI樹 app端獲…

通俗的方式解釋“零錢兌換”問題

“零錢兌換”是一道經典的算法題目&#xff0c;其主要問題是&#xff1a;給定不同面額的硬幣和一個總金額&#xff0c;求出湊成總金額所需的最少硬幣個數。如果沒有任何一種硬幣組合能組成總金額&#xff0c;返回-1。 解題思路 動態規劃&#xff1a;使用動態規劃是解決零錢兌…

GBT32960 協議編解碼器的設計與實現

GBT32960 協議編解碼器的設計與實現 引言 在車聯網領域&#xff0c;GBT32960 是一個重要的國家標準協議&#xff0c;用于新能源汽車與監控平臺之間的數據交互。本文將詳細介紹如何使用 Rust 實現一個高效可靠的 GBT32960 協議編解碼器。 整體架構 編解碼器的核心由三個主要組…

Halcon 車牌識別-超精細教程

車牌示例 流程: 讀取圖片轉灰度圖閾值分割,找車牌內容將車牌位置設置變換區域形狀找到中心點和弧度利用仿射變換,斜切車牌旋轉轉正,把車牌摳出來利用形態學操作拼接車牌號數字訓練ocr開始識別中文車牌 本文章用到的算子(解析) Halcon 算子-承接車牌識別-CSDN博客 rgb1_to_gray…

UDP透傳程序

UDP透傳程序 本腳本用于在 設備 A 和 設備 B 之間建立 UDP 數據轉發橋梁&#xff0c;適用于 A 和 B 設備無法直接通信的情況。 流程&#xff1a; A --> 電腦 (中繼) --> B B --> 電腦 (中繼) --> A 需要修改參數&#xff1a; B_IP “192.168.1.123” # 設備 B 的…

Holtek HT82V42A深度解析:CCD/CIS信號處理的集成化解決方案

——簡化圖像采集系統設計的終極利器 一、HT82V42A核心參數與外設資源 HT82V42A是Holtek專為圖像傳感器信號處理設計的模擬前端芯片&#xff0c;集成CCD/CIS信號處理與LED驅動功能&#xff0c;關鍵參數如下&#xff1a; 參數類別規格說明信號處理通道單通道CCD/CIS模擬信號輸…

詳細分析KeepAlive的基本知識 并緩存路由(附Demo)

目錄 前言1. 基本知識2. Demo2.1 基本2.2 拓展2.3 終極 3. 實戰 前言 &#x1f91f; 找工作&#xff0c;來萬碼優才&#xff1a;&#x1f449; #小程序://萬碼優才/r6rqmzDaXpYkJZF 基本知識推薦閱讀&#xff1a;KeepAlive知識點 從實戰中學習&#xff0c;源自實戰中vue路由的…

記一次誤禁用USB導致鍵盤鼠標失靈的修復過程

背景說明 在電腦上插入了一個USB hub&#xff0c;然后彈窗提示&#xff1a;“集線器端口上出現電涌”&#xff0c;點開讓選擇“重置”或者“關閉”&#xff0c;不小心點了關閉&#xff0c;結果這個usb口就被關了&#xff0c;再插任何東西都沒反應&#xff0c;找了很多辦法都恢…

小米手機如何錄制屏幕?手機、電腦屏幕錄制方法分享

大家最近有沒有遇到想記錄手機屏幕操作的情況&#xff1f; 比如精彩的游戲瞬間、有趣的視頻教程&#xff0c;或者需要錄制屏幕來制作演示材料。小米手機在這方面可是個好幫手&#xff0c;今天就來給你好好嘮嘮&#xff0c;小米手機如何錄制屏幕&#xff0c;以及后續如何處理這…

如何將JAR交由Systemctl管理?

AI越來越火了&#xff0c;我們想要不被淘汰就得主動擁抱。推薦一個人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;最重要的屌圖甚多&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 廢話不多說&#xff0c;進入正題。下面開始說如何使用 systemctl…