國密算法SM1 SM2 SM3 SM4 SM9

一、概述

  • SM1-無具體實現

SM1作為一種對稱加密算法,由于其算法細節并未公開,且主要在中國國內使用,因此在國際通用的加密庫(如Bouncy Castle)中并不直接支持SM1算法。
SM1算法的具體實現涉及國家密碼管理局的規范,通常需要使用國家指定的安全模塊(如SSF33、SC1/SC2卡)或通過國家認證的加密硬件/軟件產品來實現。
不過,如果你有合法授權并且在合規的環境下需要使用SM1算法,可能需要依賴特定的國產加密庫或SDK,比如某些商用的密碼機提供的SDK,這些SDK會封裝好SM1的加解密接口供開發者調用。
但具體的實現代碼和工具類因為涉及知識產權和國家安全規定,無法在這里直接提供。

  • SM2

非對稱加密、簽名算法
加密 解密 加簽 驗簽

可替換RSA

  • SM3

簽名算法 雜湊算法
加簽 驗簽

可替換MD5等Hash算法

  • SM4

對稱加解密密算法
加密 解密

可替換DES

  • SM9-無具體實現

目前,標準的Java庫如Bouncy Castle并不直接支持SM9算法;
因此可能需要使用特定的國密算法支持庫或遵循國家密碼管理局推薦的實現;

準備-添加依賴

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.64</version>
</dependency>

二、國密詳解

2.1 SM2實現

import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;/*** SM2實現工具類*/
public class SM2Util {/**    這行代碼是在Java中用于向安全系統添加Bouncy Castle安全提供器的。*    Bouncy Castle是一個流行的開源加密庫,它提供了許多密碼學算法和安全協議的實現。*    通過調用Security.addProvider并傳入BouncyCastleProvider對象,你可以注冊Bouncy Castle提供的安全服務和算法到Java的安全框架中。*    這樣一來,你就可以在你的應用程序中使用Bouncy Castle所提供的加密算法、密鑰生成和管理等功能。*/static {Security.addProvider(new BouncyCastleProvider());}public static KeyPair generateKeyPair() throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");keyPairGenerator.initialize(new ECGenParameterSpec("sm2p256v1"));return keyPairGenerator.generateKeyPair();}public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {Cipher cipher = Cipher.getInstance("SM2", "BC");cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}public static byte[] decrypt(PrivateKey privateKey, byte[] encryptedData) throws Exception {Cipher cipher = Cipher.getInstance("SM2", "BC");cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(encryptedData);}public static byte[] sign(PrivateKey privateKey, byte[] data) throws Exception {Signature signature = Signature.getInstance("SM3withSM2", "BC");signature.initSign(privateKey);signature.update(data);return signature.sign();}public static boolean verifySignature(PublicKey publicKey, byte[] data, byte[] signature) throws Exception {Signature sig = Signature.getInstance("SM3withSM2", "BC");sig.initVerify(publicKey);sig.update(data);return sig.verify(signature);}public static void main(String[] args) throws Exception {// 將公鑰私鑰字符串轉換為PublicKey和PrivateKey對象KeyPair keyPair = generateKeyPair();PublicKey publicKey = keyPair.getPublic();System.out.println("Public Key: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));PrivateKey privateKey = keyPair.getPrivate();System.out.printf("Private Key: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));// 待加密數據byte[] dataToEncrypt = "Hello, SM2!".getBytes();// 加密byte[] encryptedData = encrypt(publicKey, dataToEncrypt);System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encryptedData));// 解密byte[] decryptedData = decrypt(privateKey, encryptedData);System.out.println("Decrypted: " + new String(decryptedData));// 加簽byte[] signature = sign(privateKey, dataToEncrypt);System.out.println("Signature: " + Base64.getEncoder().encodeToString(signature));// 驗簽boolean isVerified = verifySignature(publicKey, dataToEncrypt, signature);System.out.println("Signature verified: " + isVerified);}}

2.2 SM3實現

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.util.encoders.Hex;/*** sm3工具類* 2024/6/25 16:29*/
public class SM3Util {/*** sm3簽名* @param signString 待簽名信息* @return 簽名*/public static String sign(String signString) {byte[] bytes = signString.getBytes();byte[] result = new byte[32];SM3Digest sm3 = new SM3Digest();sm3.update(bytes, 0, bytes.length);sm3.doFinal(result, 0);return Hex.toHexString(result);}
}

2.3 SM4實現

import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Base64;public class SM4Util {/*** 加密算法*/public static final String ALGORITHM = "SM4";/*** 加密工作模式:GCM* 數據填充模式:PKCS5Padding*/public static final String ALGORITHM_MODEL_GCM_PADDING = "SM4/GCM/NoPadding";/*** 隨機數的長度*/public static final int NONCE_LENGTH = 128;static {// 添加Bouncy Castle providerSecurity.addProvider(new BouncyCastleProvider());}/*** 使用SM4-GCM模式加密** @param plainText 需要加密的內容* @param keyBytes  密鑰字節數組* @param ivBytes   初始化向量字節數組* @return 加密之后的內容* @throws Exception 加密過程中可能發生的異常*/public static String encryptWithGCM(String plainText, byte[] keyBytes, byte[] ivBytes) throws Exception {SecretKeySpec sm4Key = new SecretKeySpec(keyBytes, ALGORITHM);GCMParameterSpec ivSpec = new GCMParameterSpec(NONCE_LENGTH, ivBytes);Cipher cipher = Cipher.getInstance(ALGORITHM_MODEL_GCM_PADDING, "BC");cipher.init(Cipher.ENCRYPT_MODE, sm4Key, ivSpec);byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(encryptedBytes);}/*** 使用SM4-GCM模式解密** @param cipherText 需要解密的內容* @param keyBytes   密鑰字節數組* @param ivBytes    初始化向量字節數據* @return 解密之后內容* @throws Exception 解密過程中可能發生的異常*/public static String decryptWithGCM(String cipherText, byte[] keyBytes, byte[] ivBytes) throws Exception {SecretKeySpec sm4Key = new SecretKeySpec(keyBytes, ALGORITHM);GCMParameterSpec ivSpec = new GCMParameterSpec(NONCE_LENGTH, ivBytes);Cipher cipher = Cipher.getInstance(ALGORITHM_MODEL_GCM_PADDING, "BC");cipher.init(Cipher.DECRYPT_MODE, sm4Key, ivSpec);byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(cipherText));return new String(decryptedBytes, StandardCharsets.UTF_8);}/*** 使用SecureRandom生成指定長度的密鑰或IV** @param length 密鑰或IV的長度(字節數)* @return 生成的隨機字節數組*/public static byte[] generateKey(int length) {SecureRandom secureRandom = new SecureRandom();byte[] bytes = new byte[length];secureRandom.nextBytes(bytes);return bytes;}/*** 生成指定長度的初始化向量(IV)** @param length IV的長度(字節數)* @return 生成的隨機字節數組*/public static byte[] generateIV(int length) {// IV的生成方式與密鑰相同,使用SecureRandomreturn generateKey(length);}public static void main(String[] args) throws Exception {String plainText = "1234測試567";// 使用隨機的byte[] key = generateKey(16);byte[] iv = generateIV(16);String cipherText1 = encryptWithGCM(plainText, key, iv);System.out.println("加密后:" + cipherText1);String decryptedText1 = decryptWithGCM(cipherText1, key, iv);System.out.println("解密后:" + decryptedText1);}
}

三、聚合工具類SMUtil

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;public abstract class SMUtil {/*** SM1作為一種對稱加密算法,由于其算法細節并未公開,且主要在中國國內使用,因此在國際通用的加密庫(如Bouncy Castle)中并不直接支持SM1算法。* SM1算法的具體實現涉及國家密碼管理局的規范,通常需要使用國家指定的安全模塊(如SSF33、SC1/SC2卡)或通過國家認證的加密硬件/軟件產品來實現。* 不過,如果你有合法授權并且在合規的環境下需要使用SM1算法,可能需要依賴特定的國產加密庫或SDK,比如某些商用的密碼機提供的SDK,這些SDK會封裝好SM1的加解密接口供開發者調用。* 但具體的實現代碼和工具類因為涉及知識產權和國家安全規定,無法在這里直接提供。**/abstract void sm1();/*** SM2生成 私鑰和公鑰* @return 私鑰和公鑰*/public static KeyPair sm2GenerateKeyPair() {try {return SM2Util.generateKeyPair();} catch (Exception e) {throw new RuntimeException(e);}}/*** sm2簽名* @param privateKey 私鑰* @param data       待簽名內容* @return 簽名*/public static String sm2Sign(PrivateKey privateKey, String data) {try {byte[] sign = SM2Util.sign(privateKey, data.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(sign);} catch (Exception e) {throw new RuntimeException(e);}}/*** sm2驗簽* @param publicKey 公鑰* @param data      待驗簽內容* @param sign      簽名* @return 是否驗簽通過*/public static boolean sm2VerifySign(PublicKey publicKey, String data, String sign) {try {return SM2Util.verifySignature(publicKey, data.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(sign));} catch (Exception e) {throw new RuntimeException(e);}}/*** sm2加密* @param publicKey 公鑰* @param data      待加密內容* @return 加密之后的內容*/public static String sm2Encrypt(PublicKey publicKey, String data) {try {byte[] encrypt = SM2Util.encrypt(publicKey, data.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(encrypt);} catch (Exception e) {throw new RuntimeException(e);}}/*** sm2解密* @param privateKey 私鑰* @param data       待解密內容* @return 解密之后的內容*/public static String sm2Decrypt(PrivateKey privateKey, String data) {try {byte[] decrypt = SM2Util.decrypt(privateKey, Base64.getDecoder().decode(data));return new String(decrypt, StandardCharsets.UTF_8);} catch (Exception e) {throw new RuntimeException(e);}}/*** sm3簽名* @param signString 待簽名信息* @return 簽名*/public static String sm3Sign(String signString) {return SM3Util.sign(signString);}/*** sm4加密* 使用傳輸的密鑰和初始化向量進行加密* @param plainText 需要加密的內容* @param key       密鑰 長度必須為16* @param iv        初始化向量 長度必須為16* @return 加密之后的內容* @throws Exception 加密過程中可能發生的異常*/public static String sm4Encrypt(String plainText, String key, String iv) throws Exception {return SM4Util.encryptWithGCM(plainText, key.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8));}/**** sm4解密* 使用傳輸的密鑰和初始化向量進行加密* @param plainText 需要加密的內容* @param key       密鑰 長度必須為16* @param iv        初始化向量 長度必須為16* @return 加密之后的內容* @throws Exception 加密過程中可能發生的異常*/public static String sm4Decrypt(String plainText, String key, String iv) throws Exception {return SM4Util.decryptWithGCM(plainText, key.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8));}/*** 目前,標準的Java庫如Bouncy Castle并不直接支持SM9算法;* 因此可能需要使用特定的國密算法支持庫或遵循國家密碼管理局推薦的實現;*/abstract void sm9();public static void main(String[] args) throws Exception {// sm2 演示// 生成密鑰對KeyPair keyPair = sm2GenerateKeyPair();System.out.println(keyPair.getPrivate());System.out.println(keyPair.getPublic());String x = sm2Sign(keyPair.getPrivate(), "12謝謝哈哈");System.out.println(sm2VerifySign(keyPair.getPublic(), "12謝謝哈哈", x));String y = sm2Encrypt(keyPair.getPublic(), "12謝謝哈哈");System.out.println(sm2Decrypt(keyPair.getPrivate(), y));// sm3 演示String s = sm3Sign("12謝謝哈哈");System.out.println(s);// sm4String key = "jsikjrblkwqb79ik";String iv = "1224567890998880";String sm4Encrypt = sm4Encrypt("123測試!@456",key, iv);System.out.println(sm4Encrypt);String sm4Decrypt = sm4Decrypt(sm4Encrypt, key, iv);System.out.println(sm4Decrypt);}
}

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

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

相關文章

Studying-代碼隨想錄訓練營day20| 235.二叉搜索樹的最近公共祖先、701.二叉搜索樹中的插入操作、450.刪除二叉搜索樹中的節點

第二十天&#xff0c;二叉樹part07&#xff0c;二叉樹搜索樹加油加油&#x1f4aa; 目錄 235.二叉搜索樹的最近公共祖先 701.二叉搜索樹中的插入操作 450.刪除二叉搜索樹中的節點 拓展&#xff1a;普通二叉樹的刪除方式 總結 235.二叉搜索樹的最近公共祖先 文檔講解&…

潔凈室(區)浮游菌檢測標準操作規程及GB/T 16292-2010測試方法解讀

潔凈室(區)空氣中浮游菌的檢測。潔凈區浮游菌檢測是一種評估和控制潔凈區(如實驗室、生產車間等)內空氣質量的方法。這種檢測的目的是通過測量空氣中的微生物(即浮游菌)數量&#xff0c;來評估潔凈區的清潔度或污染程度。下面中邦興業小編帶大家詳細看下如何進行浮游菌采樣檢測…

RK3568技術筆記九 編譯Linux詳細介紹

在編譯前需要按照前面的方法始化編譯環境&#xff0c;否則會導致編譯失敗&#xff08;若配置過則無需重復配置&#xff09;。 全自動編譯包含所有鏡像編譯&#xff0c;包括&#xff1a;uboot編譯、Kernel編譯、Recovey編譯、文件系統編譯、編譯完成鏡像的更新與打包。 按照前面…

閱讀筆記——《Large Language Model guided Protocol Fuzzing》

【參考文獻】Meng R, Mirchev M, Bhme M, et al. Large language model guided protocol fuzzing[C]//Proceedings of the 31st Annual Network and Distributed System Security Symposium (NDSS). 2024.&#xff08;CCF A類會議&#xff09;【注】本文僅為作者個人學習筆記&a…

【附精彩文章合輯】當談到程序的“通用性”與“過度設計”的困境時,我們可以通過一些具體的例子來更直觀地闡述這些解決方案

當談到程序的“通用性”與“過度設計”的困境時&#xff0c;我們可以通過一些具體的例子來更直觀地闡述這些解決方案。以下是一些示例&#xff1a; 一、明確需求與目標 例子1&#xff1a;在線購物平臺 需求分析&#xff1a;平臺需要支持用戶注冊、登錄、瀏覽商品、下單購買、…

2024ciscn 華東北awdp pwn部分wp

pwn1 break 很簡單&#xff0c;棧可執行。 先格式化字符串泄露出棧地址和canary&#xff0c;然后稍稍布置一下打orw就行 沙盒和沒有一樣 from pwn import *context(archamd64, oslinux)if __name__ __main__:# io remote(192.47.1.39, 80)io remote(192.168.142.137, 123…

初階 《操作符詳解》 10. 逗號表達式

10. 逗號表達式 exp1, exp2, exp3, …expN 注&#xff1a; 1.逗號表達式&#xff0c;就是用逗號隔開的多個表達式 2.逗號表達式&#xff0c;從左向右依次執行&#xff0c;整個表達式的結果是最后一個表達式的結果 代碼1 #include <stdio.h> int main() {int a 1;int b…

【Qt6.3 基礎教程 19】 設計直觀用戶界面(UI):Qt應用界面設計原則

文章目錄 前言理解用戶需求界面的簡潔性一致性反饋利用布局管理美化你的應用結論 前言 用戶界面(UI)設計對于任何軟件項目的成功至關重要&#xff0c;因為它是用戶與您的應用之間交流的橋梁。在Qt環境中&#xff0c;擁有一套清晰和直觀的UI設計原則&#xff0c;將有助于您創建…

解決ubuntu18.04 安裝vscode 報依賴庫錯誤,以及打不開終端的問題。

其實很簡單&#xff0c;ubuntu18.04太老了&#xff0c;官網最新版本的vscode對ubuntu18.04會有些依賴庫的問題。 一頓查資料后發現2023.11月的1.85版本正常使用&#xff0c;于是完美解決。 下載鏈接 Visual Studio Code November 2023 點擊這里下載。 下載完成&#xff0c;…

golang 獲取字符串切割之后的最后一個字符串

有些場景需要獲取字符串按某個字符切割之后&#xff0c;獲取最后&#xff0c;有個比較好的實踐分享 strings.LastIndex 如果沒有匹配到&#xff0c;則返回-1 package mainimport ("fmt""strings" )func main() {ss : []string{"", ":&quo…

數據結構需要每個都具體實現嗎?

在開始前剛好我有一些資料&#xff0c;是我根據網友給的問題精心整理了一份「數據結構的資料從專業入門到高級教程」&#xff0c; 點個關注在評論區回復“666”之后私信回復“666”&#xff0c;全部無償共享給大家&#xff01;&#xff01;&#xff01;用c的stl能刷算法題是不…

【INTEL(ALTERA)】運行配置找不到導入的自定義 makefile 項目

目錄 說明 解決方法 說明 在使用 Import Custom Makefile 用于Nios II軟件構建工具項目 選項導入項目后&#xff0c;Nios II SBT 無法將導入的自定義 makefile 識別為Nios II C/C 應用項目。因此&#xff0c;項目名稱不出現在運行配置中的列表中。 解決方法 在 "運行配置 …

clean code-代碼整潔之道 閱讀筆記(第十三章)

第十三章 并發編程 "對象是過程的抽象。線程是調度的抽象。" --James O Coplien 13.1 為什么要并發 并發是一種解耦策略。它幫助我們把做什么&#xff08;目的&#xff09;和何時&#xff08;時機&#xff09;做分解開。在單線 程應用中&#xff0c;目的與時機緊密耦…

【OpenCV 圖像處理 Python版】OpenCV 簡介及安裝

文章目錄 1.OpenCV 介紹1.1 OpenCV 的特點1.2 OpenCV 的主要模塊1.3 OpenCV 的應用場景 2.OpenCV-Python 庫3.OpenCV 安裝 1.OpenCV 介紹 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一個開源的計算機視覺和機器學習軟件庫。它由英特爾公司于1999年…

API的優勢及應用場景(淘寶API測試的詳細步驟)

一、API的優勢 API的出現為應用程序間的通信提供了一種新的方式&#xff0c;它有以下優勢&#xff1a; 1、降低開發難度 開發者可以通過API訪問其他應用程序的數據和功能&#xff0c;避免了重復開發&#xff0c;降低了開發難度。 2、提高開發效率 API提供了一種標準化的通…

Transformer 模型全解析:NLP領域的變革者與任務精粹

標題&#xff1a;Transformer 模型全解析&#xff1a;NLP領域的變革者與任務精粹 引言 Transformer 模型自問世以來&#xff0c;已成為自然語言處理&#xff08;NLP&#xff09;領域的一大突破&#xff0c;其基于自注意力機制的架構為各種語言任務帶來了革命性的進展。本文將…

使用AES,前端加密,后端解密,spring工具類,直接c就完事了

學習python的時候&#xff0c;看到很多會對參數進行加密&#xff0c;于是好奇心驅使下&#xff0c;讓我去了解了下AES加密如何在java中實現。 首先 npm install crypto-js 然后在你的方法中&#xff0c;給你們前端源碼看看&#xff0c;因為我用的ruoyi框架做的實驗&#xff…

Java中的消息隊列與事件總線設計

Java中的消息隊列與事件總線設計 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討Java中的消息隊列與事件總線設計&#xff0c;這兩者在現代分布式…

構建一個檢索增強生成(RAG)應用程序

:::tips 此文檔是LangChain官方教程的實踐總結&#xff1a;https://python.langchain.com/v0.2/docs/tutorials/rag/實踐前你需要準備&#xff1a;OPENAI_API_KEY Generator&#xff1a;根據檢索到的信息和用戶的查詢生成自然語言的回答。LANGCHAIN_API_KEY 密切監控和評估您的…

【自然語言處理系列】掌握NLP基礎:去停用詞、詞性標注與命名實體識別實戰教程

摘要&#xff1a;本系列教程專注于自然語言處理&#xff08;NLP&#xff09;中的基礎元素&#xff0c;包括去停用詞、詞性標注以及命名實體識別。這些步驟是文本預處理和分析不可或缺的組成部分。我們將通過具體的實例和技術演示&#xff0c;講解如何使用Python及其相關庫&…