?? 博主簡介:知名開發(fā)工程師
?? 出沒地點:北京
?? 2023年目標:成為一個大佬
———————————————————————————————————————————
版權聲明:本文為原創(chuàng)文章,如需轉載須注明出處,喜歡可收藏!
一. 前言
我國國家密碼管理局陸續(xù)發(fā)布了一系列國產加密算法,這其中就包括 SM1、SM2、SM3 、SM4、SM7、SM9、ZUC(祖沖之加密算法)等,SM 代表商密,即商業(yè)密碼,是指用于商業(yè)的、不涉及國家秘密的密碼技術。SM1 和 SM7 的算法不公開,其余算法都已成為 ISO/IEC 國際標準。
在這些國產加密算法中,SM2、SM3、SM4 三種加密算法是比較常見的。
算法 | 名稱 | 應用領域 | 特點 |
---|---|---|---|
SM1 | 對稱(分組)加密算法 | 芯片 | 分組長度、鑰長度均為128比特 |
SM2 | 非對稱(基于橢圓曲線ECC)加密算法 | 數據加密 | ECC橢圓曲線密碼機制256位,相比RSA處理速度快,消耗更少 |
SM3 | 散列(hash)函數算法 | 完整性校驗 | 安全性及效率與SHA-256相當,壓縮函數更復雜 |
SM4 | 對稱(分組)加密算法 | 數據加密和局域網產品 | 分組長度、密鑰長度均為128比特,計算輪數多 |
SM7 | 對稱(分組)加密算法 | 非接觸式IC卡 | 分組長度、鑰長度均為128比特 |
SM9 | 標識加密算法(IBE) | 端對端離線安全通訊 | 加密強度等同于3072位密鑰的RSA加密算法 |
ZUC | 對稱(序列)加密算法 | 移動通信4G網絡 | 流密碼 |
對稱算法 SM4 支持加解密,可替代 AES 等算法使用文章來源:http://www.zghlxwxcb.cn/news/detail-672618.html
二. 工具類
首選引入依賴,支持 java8文章來源地址http://www.zghlxwxcb.cn/news/detail-672618.html
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.56</version>
</dependency>
/**
* @Author zhoumengjun
* @Description sm4加密算法工具類
* @Date 2023/7/12 10:47
*/
public class SM4Util {
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final String ENCODING = "UTF-8";
public static final String ALGORITHM_NAME = "SM4";
// 加密算法/分組加密模式/分組填充方式
// PKCS5Padding-以8個字節(jié)為一組進行分組加密
// 定義分組加密模式使用:PKCS5Padding
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
// 128-32位16進制;256-64位16進制
public static final int DEFAULT_KEY_SIZE = 128;
/**
* 生成ECB暗號
*
* @param algorithmName 算法名稱
* @param mode 模式
* @param key
* @return
* @throws Exception
* @explain ECB模式(電子密碼本模式:Electronic codebook)
*/
private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
/**
* 自動生成密鑰
*
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @explain
*/
public static String generateKey() throws Exception {
return new String(Hex.encode(generateKey(DEFAULT_KEY_SIZE)));
}
/**
* @param keySize
* @return
* @throws Exception
* @explain
*/
public static byte[] generateKey(int keySize) throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
kg.init(keySize, new SecureRandom());
return kg.generateKey().getEncoded();
}
/**
* sm4加密
*
* @param hexKey 16進制密鑰(忽略大小寫)
* @param paramStr 待加密字符串
* @return 返回16進制的加密字符串
* @throws Exception
* @explain 加密模式:ECB
* 密文長度不固定,會隨著被加密字符串長度的變化而變化
*/
public static String encryptEcb(String hexKey, String paramStr) throws Exception {
String cipherText = "";
// 16進制字符串-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// String-->byte[]
byte[] srcData = paramStr.getBytes(ENCODING);
// 加密后的數組
byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);
// byte[]-->hexString
cipherText = ByteUtils.toHexString(cipherArray);
return cipherText;
}
/**
* 加密模式之Ecb
*
* @param key
* @param data
* @return
* @throws Exception
* @explain
*/
public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {
Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
/**
* sm4解密
*
* @param hexKey 16進制密鑰
* @param cipherText 16進制的加密字符串(忽略大小寫)
* @return 解密后的字符串
* @throws Exception
* @explain 解密模式:采用ECB
*/
public static String decryptEcb(String hexKey, String cipherText) throws Exception {
// 用于接收解密后的字符串
String decryptStr = "";
// hexString-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// hexString-->byte[]
byte[] cipherData = ByteUtils.fromHexString(cipherText);
// 解密
byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);
// byte[]-->String
decryptStr = new String(srcData, ENCODING);
return decryptStr;
}
/**
* 解密
*
* @param key
* @param cipherText
* @return
* @throws Exception
*/
public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
/**
* 校驗加密前后的字符串是否為同一數據
*
* @param hexKey 16進制密鑰(忽略大小寫)
* @param cipherText 16進制加密后的字符串
* @param paramStr 加密前的字符串
* @return 是否為同一數據
* @throws Exception
*/
public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception {
// 用于接收校驗結果
boolean flag = false;
// hexString-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// 將16進制字符串轉換成數組
byte[] cipherData = ByteUtils.fromHexString(cipherText);
// 解密
byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData);
// 將原字符串轉換成byte[]
byte[] srcData = paramStr.getBytes(ENCODING);
// 判斷2個數組是否一致
flag = Arrays.equals(decryptData, srcData);
return flag;
}
public static void main(String[] args) {
try {
String data = "2023-07-12,下午三點";
//生成key
String key = generateKey();
System.out.println("key:" + key);
//加密
String cipher = SM4Util.encryptEcb(key, data);
System.out.println("加密后:"+cipher);
//判斷是否正確
System.out.println(SM4Util.verifyEcb(key, cipher, data));// true
//解密
String res = SM4Util.decryptEcb(key, cipher);
System.out.println("解密后:"+res);
} catch (Exception e) {
e.printStackTrace();
}
}
}
到了這里,關于國密算法 SM4 加解密 java 工具類的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!