m2,sm3,sm4國(guó)密算法實(shí)現(xiàn)
pom中引入
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.71</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.0.3</version>
</dependency>
sm2非對(duì)稱加密
非對(duì)稱加密,公鑰加密,私鑰解密
package com.sm.sm2;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 描述: 國(guó)密算法生成秘鑰對(duì) - 對(duì)象 <br>
* 時(shí)間: 2022-07-14 16:01 <br>
* 作者:王林沖
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SM2KeyPairs {
/**
*公鑰
*/
private String publicKey;
/**
* 私鑰
*/
private String privateKey;
}
SM2非對(duì)稱加密輔助類
package com.sm.sm2;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
/**
* 描述: SM2非對(duì)稱加密輔助類 <br>
* 時(shí)間: 2022-07-14 16:01 <br>
* 作者:王林沖
*/
public class SM2Util {
/**
* 私鑰解密
* @param privateKey 私鑰
* @param text 加密文本
* @return 解密后文本
*/
public static String decrypt(String privateKey, String text){
// 通過(guò)密鑰解密
SM2 sm2 = SmUtil.sm2(privateKey, null);
String decryptText = sm2.decryptStr(text, KeyType.PrivateKey);
return decryptText;
}
/**
* 公鑰加密
* @param publicKey 公鑰
* @param text 預(yù)加密文本
* @return 加密后文本
*/
public static String encrypt(String publicKey, String text){
// 通過(guò)密鑰解密
SM2 sm2 = SmUtil.sm2(null, publicKey);
String encryptText = sm2.encryptBase64(text, KeyType.PublicKey);
return encryptText;
}
/**
* 獲取公鑰私鑰
* @return SM2KeyPairs 公私鑰對(duì)象
*/
public static SM2KeyPairs getKeyPairs(){
SM2 sm = SmUtil.sm2();
String privateKey = sm.getPrivateKeyBase64();
String publicKey = sm.getPublicKeyBase64();
SM2KeyPairs keyPairs = new SM2KeyPairs(publicKey, privateKey);
return keyPairs;
}
}
SM3國(guó)密算法輔助類 ,SM3混淆不可逆,類似 md5
package com.sm.sm3;
import cn.hutool.crypto.SmUtil;
/**
* 描述: SM3國(guó)密算法輔助類 ,SM3加密不可逆,類似 md5<br>
* 時(shí)間: 2022-07-14 16:49 <br>
* 作者:王林沖
*/
public class SM3Util {
public static void test() {
String encrypt = encrypt("123456");
System.out.println(encrypt);
}
public static String encrypt(String text) {
String digestHex = SmUtil.sm3(text);
return digestHex;
}
}
國(guó)密SM4對(duì)稱加密算法輔助類
對(duì)稱加密就是加密和解密都要同一個(gè) 密鑰 key
package com.sm.sm4;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
/**
* 描述: 國(guó)密SM4對(duì)稱加密算法輔助類<br>
* 時(shí)間: 2022-07-14 16:01 <br>
* 作者:王林沖
*/
public class SM4Util {
//key必須是16字節(jié),即128位
final static String key = "sm4demo123456789";
//指明加密算法和秘鑰
static SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", key.getBytes());
//加密為16進(jìn)制,也可以加密成base64/字節(jié)數(shù)組
public static String encrypt(String text) {
return sm4.encryptHex(text);
}
//解密
public static String decrypt(String text) {
return sm4.decryptStr(text);
}
public static void main(String[] args) {
String text = "hello sm4";
String encryptText = encrypt(text);
String decryptText = decrypt(encryptText);
System.out.println(encryptText + "\n" + decryptText);
}
}
我們用的是對(duì)稱加密,先生成公鑰私鑰對(duì) SM4
非對(duì)稱加密SM2可以生成公私鑰對(duì),服務(wù)端保存服務(wù)端的私鑰,客戶端保存服務(wù)端下發(fā)的公鑰,這樣,客戶端就可以用 服務(wù)端下發(fā)的公鑰 進(jìn)行數(shù)據(jù)加密,服務(wù)端接收到 request的數(shù)據(jù)密文,用自己的私鑰進(jìn)行解密即可,這樣就完成了,客戶端加密,服務(wù)端解密,注意的是非對(duì)稱加密解密是耗性能的,涉及到大數(shù)運(yùn)算,想省性能的兄弟,可以處理成類似https的方式,非對(duì)稱加密獲取對(duì)稱加密的key,數(shù)據(jù)傳輸用對(duì)稱加密,這樣性能好,我的是直接采用的對(duì)稱加密,我們是https的,https天然對(duì)數(shù)據(jù)傳輸做了保證,唯一的問(wèn)題就是處理別人F12來(lái)看,隱藏混淆對(duì)稱加密的key,增加難度。
若是需要服務(wù)端加密,客戶端解密。最好客戶端也生成一套 公鑰 和私鑰(用一套的話,服務(wù)端的私鑰會(huì)暴露在客戶端上,不安全),客戶端公鑰是服務(wù)端保存,客戶端的私鑰自己保存,就可實(shí)現(xiàn),服務(wù)端的響應(yīng)數(shù)據(jù)用客戶端的公鑰進(jìn)行加密,客戶端接收到服務(wù)端的響應(yīng)密文,用自己客戶端的私鑰解密即可,
對(duì)稱加密相對(duì)簡(jiǎn)單,客戶端和服務(wù)端的加密和解密都用同一個(gè) 密鑰 key 即可
作者:IT學(xué)習(xí)道場(chǎng)
歡迎關(guān)注微信公眾號(hào) : IT學(xué)習(xí)道場(chǎng)