Java實(shí)現(xiàn)常用加密算法SM3的方式及測(cè)試代碼
前言
在商用密碼體系中,SM3主要用于數(shù)字簽名及驗(yàn)證、消息認(rèn)證碼生成及驗(yàn)證、隨機(jī)數(shù)生成等,其算法公開。據(jù)國(guó)家密碼管理局表示,其安全性及效率與SHA-256相當(dāng)。本篇主要介紹SM3算法在Java(JDK1.8)中如何實(shí)現(xiàn),借助Java標(biāo)準(zhǔn)庫(kù)或第三方庫(kù),非原始實(shí)現(xiàn),較為基礎(chǔ)。
一、SM3是什么?
SM3算法是一種密碼散列函數(shù)標(biāo)準(zhǔn),由國(guó)家密碼管理局發(fā)布,其安全性和SHA-256相當(dāng)。 這種算法主要用于商用密碼應(yīng)用中的數(shù)字簽名和驗(yàn)證、消息認(rèn)證碼生成和驗(yàn)證、隨機(jī)數(shù)生成等。SM3算法的執(zhí)行過(guò)程包括消息填充、消息分組、消息擴(kuò)展、迭代壓縮和輸出結(jié)果。它是一種不需要密鑰的Hash算法,加密過(guò)程后無(wú)法還原為明文,即不可逆。SM3算法的執(zhí)行過(guò)程涉及將輸入的消息分成512位的分組,并對(duì)每個(gè)分組進(jìn)行填充、分組、擴(kuò)展、迭代壓縮等操作,最后輸出256位的摘要值。此外,SM3算法使用8個(gè)字寄存器來(lái)存儲(chǔ)每一輪迭代壓縮的過(guò)程數(shù)據(jù)及結(jié)果,這8個(gè)寄存器的初始值在算法開始執(zhí)行前被定義。
SM3算法的用途廣泛,包括但不限于生成消息以及文件的數(shù)字簽名,以保證信息的完整性和不可否認(rèn)性。這種算法的特性使其適用于需要高安全性的應(yīng)用場(chǎng)景,如數(shù)字簽名和驗(yàn)證,以確保信息在傳輸或存儲(chǔ)過(guò)程中的完整性和真實(shí)性。
二、實(shí)現(xiàn)方式
Java標(biāo)準(zhǔn)庫(kù)并不包含SM3算法,一般借助BC庫(kù)自行實(shí)現(xiàn),也可以使用hutool(正式項(xiàng)目中不推薦)。
1、自行實(shí)現(xiàn)
1)導(dǎo)入Maven依賴,代碼如下(示例):
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency>
2)代碼如下(示例):
import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class EncryptUtils { static { // 添加安全提供者(SM2,SM3,SM4等加密算法,CBC、CFB等加密模式,PKCS7Padding等填充方式,不在Java標(biāo)準(zhǔn)庫(kù)中,由BouncyCastleProvider實(shí)現(xiàn)) Security.addProvider(new BouncyCastleProvider()); } /** * SM3,國(guó)家商用密碼(Shang Mi3)也稱國(guó)密3,是中華人民共和國(guó)政府采用的一種密碼散列函數(shù)標(biāo)準(zhǔn),由國(guó)家密碼管理局于2010年12月17日發(fā)布。 * <p> * 輸入:待加密的字符串 * 輸出:256位(16字節(jié))或64個(gè)16進(jìn)制字符(常用) * 應(yīng)用:密碼管理、數(shù)字簽名、文件完整性校驗(yàn) * 安全性:★★☆☆☆ * * @param plainString 明文 * @return cipherString 密文 */ public static String sm3(String plainString) { String cipherString = null; try { // 創(chuàng)建SM3Digest對(duì)象 SM3Digest sm3Digest = new SM3Digest(); // 初始化SM3計(jì)算 sm3Digest.update(plainString.getBytes(StandardCharsets.UTF_8), 0, plainString.length()); // 創(chuàng)建輸出緩沖區(qū) byte[] cipherBytes = new byte[sm3Digest.getDigestSize()]; // 計(jì)算SM3摘要 sm3Digest.doFinal(cipherBytes, 0); // 輸出16進(jìn)制字符串 StringBuilder sb = new StringBuilder(); for (byte b : cipherBytes) { sb.append(String.format("%02x", b)); } cipherString = sb.toString(); } catch (Exception e) { e.printStackTrace(); } return cipherString; } }
2、hutool開源組件
1)導(dǎo)入依賴,代碼如下(示例):
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.12</version> </dependency>
2)代碼如下(示例):
import cn.hutool.crypto.SmUtil; public class EncryptUtils { static { // 添加安全提供者(SM2,SM3,SM4等加密算法,CBC、CFB等加密模式,PKCS7Padding等填充方式,不在Java標(biāo)準(zhǔn)庫(kù)中,由BouncyCastleProvider實(shí)現(xiàn)) Security.addProvider(new BouncyCastleProvider()); } /** * SM3,國(guó)家商用密碼(Shang Mi3)也稱國(guó)密3,是中華人民共和國(guó)政府采用的一種密碼散列函數(shù)標(biāo)準(zhǔn),由國(guó)家密碼管理局于2010年12月17日發(fā)布。 * <p> * 輸入:待加密的字符串 * 輸出:256位(16字節(jié))或64個(gè)16進(jìn)制字符(常用) * 應(yīng)用:密碼管理、數(shù)字簽名、文件完整性校驗(yàn) * 安全性:★★☆☆☆ * * @param plainString 明文 * @return cipherString 密文 */ public static String sm3(String plainString) { return SmUtil.sm3(plainString); } }
三、測(cè)試
我這里隨機(jī)找了一個(gè)在線SM3加密的某網(wǎng)站做對(duì)比,如下:
代碼如下(示例):
public class EncryptUtils { ... public static void main(String[] args) { String plainString = "hello world, hello java!"; String sm3 = sm3(plainString); System.out.println("加密前: " + plainString); System.out.println("加密后: " + sm3); } }
代碼運(yùn)行截圖:
某網(wǎng)站截圖:
總結(jié)
到此這篇關(guān)于Java實(shí)現(xiàn)常用加密算法SM3的方式及測(cè)試代碼的文章就介紹到這了,更多相關(guān)Java常用加密算法SM3內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用位運(yùn)算實(shí)現(xiàn)加減乘除詳解
這篇文章主要為大家詳細(xì)介紹了Java如何使用位運(yùn)算實(shí)現(xiàn)加減乘除,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Java有一定的幫助,感興趣的可以了解一下2023-05-05關(guān)于設(shè)置Mybatis打印調(diào)試sql的兩種方式
這篇文章主要介紹了關(guān)于設(shè)置Mybatis打印調(diào)試sql的兩種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Spring?BeanDefinition父子關(guān)系示例解析
這篇文章主要為大家介紹了Spring?BeanDefinition父子關(guān)系示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08使用java實(shí)現(xiàn)百萬(wàn)級(jí)別數(shù)據(jù)導(dǎo)出excel的三種方式
這篇文章主要介紹了使用java實(shí)現(xiàn)百萬(wàn)級(jí)別數(shù)據(jù)導(dǎo)出excel的三種方式,有些業(yè)務(wù)系統(tǒng)可能動(dòng)輒涉及到百萬(wàn)上千萬(wàn)的數(shù)據(jù),用正常的方法效率就變得很低,今天我們來(lái)看看這幾種實(shí)現(xiàn)思路2023-03-03使用Feign實(shí)現(xiàn)微服務(wù)間文件下載
這篇文章主要為大家詳細(xì)介紹了使用Feign實(shí)現(xiàn)微服務(wù)間文件下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例
這篇文章主要介紹了Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08maven多profile 打包下 -P參和-D參數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了maven多profile 打包下 -P參和-D參數(shù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Java實(shí)現(xiàn)獲取內(nèi)網(wǎng)的所有IP地址
這篇文章主要介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)獲取內(nèi)網(wǎng)的所有IP地址,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的參考價(jià)值,快跟隨小編一起學(xué)習(xí)一下吧2022-06-06