javasm4国密算法加密、解密
1.准备⼯作
  所需jar包:
  bcprov-jdk15on-1.59.jar
  commons-lang3-3.1.jar
  20200901
  对应的maven依赖
<!--sm3,sm4加密算法-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.66</version>
</dependency> 
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
pto.Cipher;
pto.KeyGenerator;
pto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
/**
* sm4加密算法⼯具类
* @explain sm4加密、解密与加密结果验证
*          可逆算法
* @author Marydon
* @creationTime 2018年7⽉6⽇上午11:46:59
* @version 1.0
* @since
*@****************************
*/
public class Sm4Util {
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;
/**
* ⽣成ECB暗号
* @explain ECB模式(电⼦密码本模式:Electronic codebook)
* @param algorithmName
*            算法名称
* @param mode
*            模式
* @param key
* @return
* @throws Exception
*/
private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
Cipher cipher = Instance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
}
2.SM4加密
  第⼀步:产⽣密钥
  ⽅式⼀:系统⽣成密钥
/**
* ⾃动⽣成密钥
* @explain
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
*/
public static byte[] generateKey() throws Exception {
return generateKey(DEFAULT_KEY_SIZE);
}
/
**
* @explain
* @param keySize
* @return
public static byte[] generateKey(int keySize) throws Exception {
KeyGenerator kg = Instance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);    kg.init(keySize, new SecureRandom());
ateKey().getEncoded();
java64位
  ⽅法⼆:⾃⼰提供16进制的密钥
  第⼆步:加密
/**
* sm4加密
* @explain 加密模式:ECB
*          密⽂长度不固定,会随着被加密字符串长度的变化⽽变化
* @param hexKey
*            16进制密钥(忽略⼤⼩写)
* @param paramStr
*            待加密字符串
* @return 返回16进制的加密字符串
* @throws Exception
*/
public static String encryptEcb(String hexKey, String paramStr) throws Exception {
String cipherText = "";
// 16进制字符串-->byte[]
byte[] keyData = ByteUtils.fromHexString(hexKey);
// String-->byte[]
byte[] srcData = Bytes(ENCODING);
// 加密后的数组
byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);
// byte[]-->hexString
cipherText = HexString(cipherArray);
return cipherText;
}
/
**
* 加密模式之Ecb
* @explain
* @param key
* @param data
* @return
* @throws Exception
*/
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);
}
3.SM4解密
/**
* sm4解密
* @explain 解密模式:采⽤ECB
* @param hexKey
*            16进制密钥
* @param cipherText
*            16进制的加密字符串(忽略⼤⼩写)
* @return 解密后的字符串
* @throws Exception
*/
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;
}
/**
* 解密
* @explain
* @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);
4.加密数据校验
/**
* 校验加密前后的字符串是否为同⼀数据
* @explain
* @param hexKey
*            16进制密钥(忽略⼤⼩写)
* @param cipherText
*            16进制加密后的字符串
* @param paramStr
*            加密前的字符串
* @return 是否为同⼀数据