引入依赖:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.54</version>
</dependency>
完整代码:
package utils;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import java.util.UUID;
public class Sm4Util {
static
{
Security.addProvider(new BouncyCastleProvider());
}
private static final String ENCODING = "UTF-8";
public static final String ALGORITHM_NAME ="SM4";
public static final String ALGORITHM_NAME_CBC_PADDING ="SM4/CBC/PKCS5Padding";
public static final int DEFAULT_KEY_SIZE = 128;
public static void main(String[] args) throws Exception {
String s = generateKeyString();
System.out.println("密钥:"+s);
String uuid= UUID.randomUUID().toString();
System.out.println("带加密数据:"+uuid);
String s1 = encryptTextSm4(s, uuid);
System.out.println("加密数据:"+s1);
String s2 = decodeTextSm4(s, s1);
System.out.println("解密数据:"+s2);
String s3 = encryptTextSm3(uuid);
System.out.println(verify(uuid,s3));
}
public static String encryptTextSm4(String hexKey, String paramStr) throws Exception {
String result = "";
byte[] keyData = ByteUtils.fromHexString(hexKey);
byte[] srcData = paramStr.getBytes(ENCODING);
byte[] cipherArray = encrypt_Cbc_Padding(keyData, srcData);
result = ByteUtils.toHexString(cipherArray);
return result;
}
public static String decodeTextSm4(String hexKey, String text) throws Exception {
String result = "";
byte[] keyData = ByteUtils.fromHexString(hexKey);
byte[] resultData = ByteUtils.fromHexString(text);
byte[] srcData = decrypt_Cbc_Padding(keyData, resultData);
result = new String(srcData, ENCODING);
return result;
}
public static String encryptTextSm3(String text) throws UnsupportedEncodingException {
byte[] bytes = text.getBytes(ENCODING);
byte[] hash = hash(bytes);
String s = ByteUtils.toHexString(hash);
return s;
}
public static byte[] hash(byte[] srcData){
SM3Digest digest=new SM3Digest();
digest.update(srcData,0,srcData.length);
byte[] bytes = new byte[digest.getDigestSize()];
digest.doFinal(bytes,0);
return bytes;
}
public static boolean verify(String srcStr,String sm3HexString) throws Exception{
boolean flag=false;
byte[] srcStrData = srcStr.getBytes(ENCODING);
byte[] sm3HexStringData = ByteUtils.fromHexString(sm3HexString);
byte[] hash = hash(srcStrData);
if(Arrays.equals(hash,sm3HexStringData))
{
flag= true;
}
return flag;
}
public static String generateKeyString() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
kg.init(DEFAULT_KEY_SIZE, new SecureRandom());
byte[] encoded = kg.generateKey().getEncoded();
return ByteUtils.toHexString(encoded);
}
public static byte[] encrypt_Cbc_Padding(byte[] key, byte[] data) throws Exception {
Cipher cipher = generateCbcCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
private static Cipher generateCbcCipher(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, generateIV());
return cipher;
}
public static AlgorithmParameters generateIV() throws Exception {
byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
AlgorithmParameters params = AlgorithmParameters.getInstance(ALGORITHM_NAME);
params.init(new IvParameterSpec(iv));
return params;
}
public static byte[] decrypt_Cbc_Padding(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = generateCbcCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
}