springboot使用國產(chǎn)加密算法方式,sm2和sm3加解密demo
需求
前后端交互的加解密算法,要求使用國產(chǎn)的
1、SM1分組密碼算法
SM1是由國家密碼管理局編制的一種商用密碼分組標(biāo)準(zhǔn)對稱算法,分組長度和密鑰長度均為128位,算法的安全保密強(qiáng)度及相關(guān)軟硬件實(shí)現(xiàn)性能與AES算法相當(dāng),目前該算法尚未公開,僅以IP核的形式存在于芯片中,調(diào)用該算法時(shí),需要通過加密芯片的接口進(jìn)行調(diào)用。
2、*SM2公鑰密碼算法
SM2算法是國家密碼據(jù)于2010年12月17日發(fā)布的國密標(biāo)準(zhǔn)橢圓曲線加密算法,是一種基于ECC算法的非對稱加密算法,SM2橢圓曲線公鑰密碼算法是我國自主設(shè)計(jì)的公鑰密碼算法,包括SM2-1橢圓曲線數(shù)字簽名算法,SM2-2橢圓曲線密鑰交換協(xié)議,SM2-3橢圓曲線公鑰加密算法,分別用于實(shí)現(xiàn)數(shù)字簽名密鑰協(xié)商和數(shù)據(jù)加密等功能。
SM2算法與RSA算法不同的是,SM2算法是基于橢圓曲線上點(diǎn)群離散對數(shù)難題,對于一般橢圓曲線的離散對數(shù)問題,目前只存在指數(shù)級計(jì)算復(fù)雜度的求解方法。
與大數(shù)分解問題及有限域上離散對數(shù)問題相比,橢圓曲線離散對數(shù)問題的求解難度要大得多。
因此,在相同安全程度要求下,橢圓曲線密碼較其他公鑰密碼所需的秘鑰規(guī)模要小得多。
相對于RSA算法,256位的SM2密碼強(qiáng)度已經(jīng)比2048位的RSA密碼強(qiáng)度要高。
其加密強(qiáng)度為256位,密鑰長度短,安全程度高,可用于數(shù)字簽名、密鑰交換、公鑰加密。
3、*SM3密碼雜湊算法
SM3是我國采用的一種密碼散列函數(shù)標(biāo)準(zhǔn),由國家密碼管理局于2010年12月17日發(fā)布。
相關(guān)標(biāo)準(zhǔn)為“GM/T 0004-2012 《SM3密碼雜湊算法》”。
據(jù)國家密碼管理局表示,其安全性及效率與SHA-256相當(dāng),也叫密碼雜湊算法,屬于哈希(摘要)算法的一種,功能與MD5,SHA-1相同。
對長度小于264比特的消息m,經(jīng)過填充、壓縮,生成256位雜湊值,和SM2算法一起被公布,該算法位不可逆的算法。
在商用密碼體系中,SM3主要用于數(shù)字簽名及驗(yàn)證、消息認(rèn)證碼生成及驗(yàn)證、隨機(jī)數(shù)生成等,可滿足多種密碼應(yīng)用的安全需求,算法已公開。
4、*SM4分組密碼算法
SM4是國家密碼管理局發(fā)布的分組密碼算法,于2012年3月正式公布。
與DES和AES算法類似,SM4是一種分組密碼算法。其分組長度為128bit,密鑰長度也為128bit。
SM4算法加/解密算法是對合運(yùn)算,只是使用輪密鑰相反,其中解密輪密鑰是加密輪密鑰的逆序。
加密算法與密鑰擴(kuò)展算法均采用32輪非線性迭代結(jié)構(gòu)(Feistel),以字(32位)為單位進(jìn)行加密運(yùn)算,每一次迭代運(yùn)算均為一輪變換函數(shù)F。
目前主要用于無線局域網(wǎng)產(chǎn)品。
方案
使用場景:前后端交互使用sm2,后端存儲密碼時(shí)使用sm3
1、pom依賴
<dependency> ? ? ?<groupId>org.bouncycastle</groupId> ? ? ?<artifactId>bcprov-jdk15on</artifactId> ? ? ?<version>1.60</version> </dependency>
2、demo示例
public static void main(String[] args) throws InvalidCipherTextException { System.out.println("sm2測試開始-----------"); X9ECParameters sm2EcParameters = GMNamedCurves.getByName("sm2p256v1"); ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.getCurve(),sm2EcParameters.getG(),sm2EcParameters.getN()); ECKeyPairGenerator keyPairGenerator =new ECKeyPairGenerator(); try { keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG"))); AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair(); //私鑰 BigInteger privateKey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD(); String privateKeyHex = privateKey.toString(16); System.out.println("私鑰:" + privateKeyHex); //公鑰 ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ(); String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false)); System.out.println("公鑰:" + publicKeyHex); String str = SM2Util.encrypt("test",publicKeyHex); System.out.println("加密結(jié)果:"+str); try{ String res = SM2Util.decrypt(str,privateKeyHex); System.out.println("解密結(jié)果:"+res); }catch (Exception e){ e.printStackTrace(); } System.out.println("sm2測試結(jié)束-----------"); System.out.println("sm3測試開始-----------"); String sm3 = SM3Util.sm3Sign("test"); System.out.println("sm3加密結(jié)果"+sm3); if(SM3Util.sm3Verify("test",sm3)){ System.out.println("sm3驗(yàn)證成功"); }else { System.out.println("sm3驗(yàn)證失敗"); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } }
3、結(jié)果
sm2測試開始-----------
私鑰:bdda9f26ae5884e3f5410902aec78cab6c3f4a7c9d9578e6a9c60ae977d6d645
公鑰:041870142d71f518ce9bd6458b4b41b4d49e7fbfd9a14440eb49ed9bbb352e72739d2e2369722ba381db2a7add5093c7a976df49496cb5c08a56e87db877f4e866
加密結(jié)果:0445fd5bce247f30cd507314830f57d3278dfdfab3e8fdc6acb93c60a3a4b6bbc09150c065153389d7b0c3581a0a0fd5c3ffe59ed53855a289a98ce9705a5230b752aa8535980ba08db6319eef0f3c1140ccd3d0849f0c78a4478189c1736de07b27254794929c9de9
解密結(jié)果:test
sm2測試結(jié)束-----------
sm3測試開始-----------
sm3加密結(jié)果55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23
sm3驗(yàn)證成功
4、前端加密
const sm2 = require('sm-crypto').sm2 const cipherMode = 0 // 1 - C1C3C2,0 - C1C2C3,默認(rèn)為1,這里用0
加密
let base = Base64.encode(msgString); let encryptData = sm2.doEncrypt(base, publicKey, cipherMode) // 加密結(jié)果 conso.log("加密結(jié)果:",encryptData);
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java使用正則表達(dá)為數(shù)字添加千位符的簡單方法
這篇文章主要介紹了java使用正則表達(dá)為數(shù)字添加千位符的簡單方法,需要的朋友可以參考下2014-04-04springboot攔截器Interceptor的使用,你都了解嗎
springmvc 中的攔截器可以對請求進(jìn)行判別,在請求到達(dá)控制器之前,把非法的請求給攔截掉下面來說一說, 它在springboot中的使用,感興趣的朋友一起看看吧2021-07-07在IntelliJ?IDEA中配置SSH服務(wù)器開發(fā)環(huán)境并實(shí)現(xiàn)固定地址遠(yuǎn)程連接的操作方法
本文主要介紹如何在IDEA中設(shè)置遠(yuǎn)程連接服務(wù)器開發(fā)環(huán)境,并結(jié)合Cpolar內(nèi)網(wǎng)穿透工具實(shí)現(xiàn)無公網(wǎng)遠(yuǎn)程連接,然后實(shí)現(xiàn)遠(yuǎn)程Linux環(huán)境進(jìn)行開發(fā),本例使用的是IDEA2023.2.5版本,感興趣的朋友跟隨小編一起看看吧2024-01-01Springboot配置security basic path無效解決方案
這篇文章主要介紹了Springboot配置security basic path無效解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09java中String、StringBuffer與StringBuilder的區(qū)別
這篇文章主要介紹了java 中String和StringBuffer與StringBuilder的區(qū)別,在開發(fā)過程中經(jīng)常會用到String這個(gè)類進(jìn)行操作。需要的朋友可以收藏下,方便下次瀏覽觀看2021-12-12Java上傳文件錯(cuò)誤java.lang.NoSuchMethodException的解決辦法
今天小編就為大家分享一篇關(guān)于Java上傳文件錯(cuò)誤java.lang.NoSuchMethodException的解決辦法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01打開.properties中文顯示unicode編碼問題以及解決
這篇文章主要介紹了打開.properties中文顯示unicode編碼問題以及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01