Files
shz-backend/ruoyi-common/src/main/java/com/ruoyi/common/utils/SM4Utils.java
2026-01-09 20:13:01 +08:00

212 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.common.utils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SM4Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final String ENCODING = "UTF-8";
public static final String ALGORITHM_NAME = "SM4";
/**
* 加密算法/分组加密模式/分组填充方式
* PKCS5Padding-以8个字节为一组进行分组加密
* 定义分组加密模式使用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;
private static Pattern p = Pattern.compile("\\s*|\t|\r|\n");
/**
* 自动生成密钥
*
* @return
* @explain
*/
public static String generateKey() {
try {
return new String(Hex.encode(generateKey(DEFAULT_KEY_SIZE)));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @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();
}
/**
* 生成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;
}
/**
* sm4加密
*
* @param hexKey 16进制密钥忽略大小写
* @param paramStr 待加密字符串
* @explain 加密模式ECB
* 密文长度不固定,会随着被加密字符串长度的变化而变化
*/
public static String encryptEcb(String hexKey, String paramStr) {
return encryptEcb(hexKey, paramStr, true);
}
/**
* sm4加密
*
* @param hexKey 16进制密钥忽略大小写
* @param paramStr 待加密字符串
* @param isHex 是否返回16进制的加密字符串
* @return 返回16进制的加密字符串或base64String
* @explain 加密模式ECB
* 密文长度不固定,会随着被加密字符串长度的变化而变化
*/
public static String encryptEcb(String hexKey, String paramStr, boolean isHex) {
try {
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
if (isHex) {
cipherText = ByteUtils.toHexString(cipherArray);
} else {
// byte[]--> base64String
cipherText = Base64Utils.encodeToString(cipherArray);
if (cipherText != null && cipherText.trim().length() > 0) {
Matcher m = p.matcher(cipherText);
cipherText = m.replaceAll("");
}
}
return cipherText;
} catch (Exception e) {
return paramStr;
}
}
/**
* 加密模式之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) {
return decryptEcb(hexKey, cipherText, true);
}
/**
* sm4解密
*
* @param hexKey 16进制密钥
* @param cipherText 16进制的加密字符串忽略大小写
* @return 解密后的字符串
* @throws Exception
* @explain 解密模式采用ECB
*/
public static String decryptEcb(String hexKey, String cipherText, boolean isHex) {
// 用于接收解密后的字符串
String decryptStr = "";
// hexString-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
byte[] cipherData;
if (isHex) {
// hexString --> byte[]
cipherData = ByteUtils.fromHexString(cipherText);
} else {
// base64String --> byte[]
cipherData = Base64Utils.decodeFromString(cipherText);
}
try {
// 解密
byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);
// byte[]-->String
decryptStr = new String(srcData, ENCODING);
} catch (Exception e) {
e.printStackTrace();
}
return decryptStr;
}
/**
* 解密
*
* @param key
* @param cipherText
* @return
* @throws Exception
* @explain
*/
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);
}
public static void main(String[] args) {
//加密
// System.out.println(encryptEcb("06e6af183547026dd66eae8c0827acc7","a3b129c34a0b06800c7506075ebee2af"));
//解密
System.out.println(decryptEcb("8c10e08760bb0f8465c8e8390c8c4670","fd24f99e4007788b0ea7a003ab96f7bcd0b677a5925ba1b111cadda9c108665d8d5788bac31694a2d5f83d629c74a4addde17d2fb32a5e4fa5068d857fec04c675de24b58d84de6331eebd6c191f5a4b0bddc30b0fe2462b8911c54d6149a1991509bdbb7de00257b753cd165e90e1b5cfaa1cf994e01d21df3725599c058ccf29ea5c6cc06ce2b91828c890bb164d61bc706a5093a814173605c0b36536d77a425f178f84e95d4058ca28811c7ddecce3515327555ff536579832e3ed0a26adabbf2ac22e443c12579d8d9bf066faf8db8d26ec316378dd12e97f7bdea0c51cdfb5c8f4ad199c4db29623bca807d9a26ec4fd1e59b562b588b8923253608eaa7c5d1ba4e47cf8d6eece514836cf8d18991157befab3df18bd8d38a5e1e208118977454f41f5327e02aad1d18203a1e0e71b7fc75510f532879ad037ff299a756ac1d665773ffd12e362825c45c4fd395e51a8f2a0cd94a2a671d09ef49f3e4845b58fd9959172460bb446c7911677a74e60259c6b1df5f9ddabc7da365b7ed285150de1f4ca551f43535deff943e9c63ec979bda9a7bb402f8f654cd5bf3b327a7671331e112d02fa6ad552391a032a53c512d469d13a07ae83e5c458caecad32587ebb06171b1db299e80b3bd2416c03579e679f5f0254900f97d216b296faa5fdd5d5b00d6da52bcd327cb66656c5dd659c6bd343070399fa8653e72734ce6cedba70c68c189f6a58258816c2c02ba5b368c5c2ed00c25ebd7a8e71534a4bfad9c06586c0111cfa9445345dce93330b53f6af32931ae3a8b6b2821dc8623846fda300eeb69484340c958e588521a903ff1ec2beb14d9d6c78506ff79957722a191406ea6345252e7dec630cb46869d4cb3160db78fbac93927598649de7ecf386138864cef931d56d1013936a922c46c3ed5d924a37e79142d5514fa46e48e0a38e1575c55d2d1053fe7cea649bc005ee49584d2f42a7525285ada0dbcbcfeab4c09efe2cf981f56ec18816d5cd5f90098bbba2257d8353922c4b2f009762f144031ebd0e5c6d7ce9437a4bde7f6e4972494242f69896947baf49ee71a50f2cfec157d9d5c5106e3a659153401d2df2d2f09e07fc62505e9995e6a3f206a0fd0fac830e76598bcae22d409dcf1ddcd134e0c3bb2db4d1bcb5fd4b65d55a9f268859aa16207ed998cc0ddf6cb840b38454aec10e5770e7150f0ce97db9bce166eefe096f26110ee71aa27cdbca6e42c3cd1a05179e5aa31af8f9ec6e54de3f4e51e739a66376025615c55b1eafaecade0333abe0397ffaa75d72a82c6d75df305c3d1b3d30c29058585dc4f1675c5afb1f9982c9c6f4caa6cc2ce90e57df8d0c26cb5c8e8e839f6361208fc8038882ed2914857585e76a72cde36ad6d144395eac688fb5fa8d46338df9639fb8bf86e20b39054a94981306408326161382d14e5bae5d641c44883cf13f22d9ccf1f0c06577c383f8dd230208a2920f59fe926f694a3790c62d647f4b4a0f609962a5caa015661549f2a6b4a9ed1d3ad0f5dd3a7877ce78f1d85ae4d97ca2e153e13d443cc4c5a06b6111ff989b25dea29eb85093623507f342c89d212aa72c4e5839fdfde5c5d905299c8ade53b816e382cb73aceec12af81154d64ca0cbcc3c98c317395dd726aafa975e69e700106a1b42b20f7ea77fb881980d19f6b2bee678e551736d1667726420f89fa5a3e3d28ee29414e3b25b83011b127928dc4ba49e003da2e2e5b4f8c01d002d229f48d309bda4b53ec8c0ae155df5f91c11ad3a3a2c6a0217f9a47feef49411fcbd0228e5593d60185701e0c377e5c47958d52b0f706b9be26998bffae5199cda51af5ad7fa79bf46dcd8fbb1f135827f791b547d870014ca69f5bfb5b0a73180d75c6d9f13603e4506a174a8607fe85477760c904099d7d4696716aa9bb1c8744a18fb1ae37210349a811423b1165afc28b500d1095e16a1594364c012f5f6cc3bd9f64a64187b01bcda4875ae7646540548a465c2b56caf38d98ce6a5d0f75b3c074fb2248e01cae9eb3e78dbc01302054c738d0be6a7ed37761b337c0343b453e06c9700dee8fc00a705e4a747e1a5d46588c8bace9c68eb3832f0600e46f54e85a4a3a44ea0c29c69b5c5d6b6491f0a3f0bdbd123bafe3f3dd987fcc52e30c5c6cf1e9f02f998ea2791dc72cc75dac6033198c38cec44671465120ec946145b7171a63234b531e54253f92ed2c115cfe700d35e103741744d5c29f5e466109e7aba25fb9bcc38c472ae17108e3027b68d97b8d1d90c880d92a919cbce9881d6905a33f6ce5421c570a57f056ba70966e6472f49cd3d4f48c3261e0b7ae75cb34394d692ff2b80e0d596123811bbabccf90991b5b2dc17623a0f547478fef1a1cc2df258785141e7153030d8afb58c1e214632124436cbab0c21996b5dc27704635a4b27531cfddeeadcf90fd57c681bc2b0527ffd0106692d57f36af689ea77b06bc4030fad5cdf7e60e1f03d168bd3ff798f55a629f65b8fe731fc872ad44f58176d46442e5e3afcdb69302ad58802b5ed684d3e6365a77d7e931fc691b6e7d6c63897ba5c70e6e94eb7db177a19e6d97905769fd2a40ce8ef94dc14eeced2b8dc90dd423b8255f5e926662387a52c628af72e760b94a55ea5eccc41865c503e738047d6351a4ab17b2d5139a29c830f37ba364830ecd5c47d987ae1be041b7ad0d29fa769e78266b51f49fe738d132ec7bd9c005be3b8caae434d11078cb9483ede152664954dedf3ca5aa508fdc4ab00120bfac8191851cf335a6197fb33b0dd17de0abfb2a045cf85f4a0dfcfb10846b1c2e10cb776727e27c5987a86fd8396b807c7a50b0a7a5e83cb64187da3804e24c180b16c4da848ca211a88e869b4caa5f8a486b4c41ff119497f0ac1942274c2d9817c91bb03498bc90306716a254b4e13c8327270511d71b5dfa9a44fda1f979e9d8dc8d3cb0ac5df4f5fe4940936d8e665c5667d397b9c73e13fdf79e99d8484cb940dc2451ca0a3b5cff3eebe53f7ea3d6c97a1eb1959fde7353a9d5e27c7ec4f38dcc42e8319cf150d300a0209f5de6a9d2d43450e568d236715455e2632face4c24accb6c3a33d4a6ae4f014a78866195306cc55e817836393641f6f49c05f50e3862222b0ca344ab1059e8be26937066be9e5ed12445cab67dc2de15fa26c65eaa0b0933c22c2081accc692e4a0ce463b3609038d0dea1360181f3382f00b30e61e908b8bbd5acb7b65660a97a1c4d4ba7ccce2da3095a5d8d181abc916fd831f18478db3f1590681afb55f62273d670130fa2a195d7e2a4365de887a265513df5e49e31b51ddb54807f821fdedd7eea0779dfdfcf3e64299046d6e62cc3b34d4a826f813f627bbed52964f449fe4a714ed9be8b60f54073654d749642c069780f06a34d56f5f12c29516901382568a6d3493947b046f05bcfe03ef95666e8e6d760d88f57ccf50349af4fb0e7efe2b08c94937313750dfb84d32a08b20599c3ee12a8cd6b1496cb1a069e98797a8f789743172732e35090009cffd1686809c199ef527a89d8ebbd05dfef79c6a9a958acd89aa3ed9aa648627fe62cb760c9f10e6986b0069973bf7afa4d138b56464e7f69824d852accec36dd384083215aedd55f37fc79940a0a8832397ac5e3336a436324789247c51c3e948bdcf6fb3396fe75aa8dae4f29c58cf835dc6ff2b3c4d6c236f3ce8064c8bc7a8536118a36414c842fc1a8ab6e71242ecb655df0092dee733b137feaff4b6bfc47558cbd04b3684f7f8dd31a72fcfb104f3c9568edb9da4f0826512b65b87357f45e6b7d9813b3cb03b1c3f2e1363746925e27c26e8ad0c921803c1cdf7210665971afbd8d81eda9216a25ab8ff5bb224e8f6c759e46f7254e5716db943b782a9d16451e4de2e86d3b4444b8c060aedb32d630865badb0b96a1501aac1a6f67bd74cd0b0999b0ab8173df3ad1cf6845d13e68f09853f1b57b51381f85a792afa61e2d21bac341f78cfbfa52ccf586b0572d6dff5a91e57b81186fdc52c522ff72811fe1c5d52bdee4ce6ea290f0eff38820fa8eba22117ef88797aeeeaabc66ac1ae1ec674e75c7162e10304783f2ad497361f39078d92ab21ee7d26e24fb10466665c8cc4554c11984e584b8fccaa1a19fa60db2bb6fc96d5e518a8c1ab9a8223fa4a790e15443d82d88b78deb561c423f995bd46c0cf356993227f6e90cd4311fe8624ada05ecf9a1f9d0ba9c1935c84a8763f0069e6956c75a20f2a70a84b7e25133a2e35ffa81ea74978e03881c0fceff4f2fb8a757ee4e3ff752007decda9a91b2522b0a54f8369ac878fba41ecc93396008c0d45ac019dcde8b3fa001583c740a507af08818465bedc7b103a4a8884d8fbf653f4e7a0c6b28fbe3507c7fe680429cb15def6e817c2e184fc32ff5f97a931a3f873ccce5f55b727eb270e18f343639102b5dabad5b727b7c76d80e6f61fa9b97b52c61fc703f8c8abbdf5355aaf72f22858a102ffee2fd147dd00d53141b734ee03ed9b587572f89dc2e251d207781b78e92a370cc456b3f297ea63155d530962c2159d23ea02735e5fdacecdae91888196f30c1bef6ab4643344f632e8778d6b2d102d69207f65c20e8976ba230a4c8e2c18e60d900352748570e9198d7b836cfb7f81b4d83bc52a9f6d146cc9f50c4f0d920c5b85ef51c6444fcb8b9c3e42862c345ea9ddd6b33370d36ed2779b6ca46072806e24799758b01eb7ac6570589f79b382825d4fb6ef5f02a58c6b2431c466723ee41a78f12fbfdbb2cf51514627284683f1808541cfee130aa4df80c89bd6cb92f7525a786bcd527decf10025e46291bac454a2ecab6423d9ec9327a0965abccafe69e02c83cf7faddaf6c2aa80e23261ca2174b28e36d4c46d71e68f03b4a52d8e010f36a1b12f51254c0c0b6d3ae749dc4dc292f4941353a664fafb8b2ef40d14cc3f30ba3e33b6478330e5070d3b5193c4e8dca4db9f9b2b126866ff75f11e84b98b7a7abcafa65366957e968e520317bbd42cef26008074a1ca4773e38a0e24aa4e89d74778afe2711ce979f20e8a1673b42f987dae34979fa4c832af2134f0cc625d03b77392975c344c7cb028edf407b3d987aabcd8386c29420564dff494bb4ddbbb221de3b04d01be347ac64e237a946f1bc27c264cd8d0d5f090f4bf01baf7fd652ea0eb4ab3707fe50dadb68fc78e3f4b2ee86fa39349a7bfeb6c68ed5082d9848efd93b36b6147ba5c6135d58925491f5b4119e94337ba8c5f78482d777fcc8b41059a30b956f2279c8e7e573fd220ce8f890635282093c0aea98fa8db8c29c229672d8ea3706d6757870ab6db03e881e48427c929b7478c345121289c05e43ec7bf6e1eda28"));
// System.out.println(generateKey());
}
}