001package top.cenze.utils.crypt; 002 003import org.bouncycastle.jce.provider.BouncyCastleProvider; 004import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; 005 006import javax.crypto.Cipher; 007import javax.crypto.KeyGenerator; 008import javax.crypto.spec.SecretKeySpec; 009import java.security.Key; 010import java.security.SecureRandom; 011import java.security.Security; 012import java.util.Arrays; 013 014/** 015 * SM4国密加密解密工具 016 * 017 * @author chengze 018 * @date 2023-11-14 22:36 019 */ 020public class SM4Util { 021 022 private static final String ENCODING = "UTF-8"; 023 public static final String ALGORIGTHM_NAME = "SM4";//密钥名称 024 public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";//密码的分组方式SM4/ECB/PKCS7Padding 025 public static final int DEFAULT_KEY_SIZE = 128;//默认的key值长度128 026 027 public SM4Util() { 028 } 029 030 static { 031 Security.addProvider(new BouncyCastleProvider()); 032 } 033 034 /** 035 * @Description:生成ecb暗号 036 */ 037 private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception { 038 Cipher cipher = Cipher.getInstance(algorithmName,BouncyCastleProvider.PROVIDER_NAME); 039 Key sm4Key = new SecretKeySpec(key, ALGORIGTHM_NAME); 040 cipher.init(mode, sm4Key); 041 return cipher; 042 } 043 044 /** 045 * @Description:自动生成密钥 046 */ 047 public static String generateKey() throws Exception { 048 return generateKey(DEFAULT_KEY_SIZE); 049 } 050 051 public static String generateKey(int keySize) throws Exception { 052 KeyGenerator kg = KeyGenerator.getInstance(ALGORIGTHM_NAME, BouncyCastleProvider.PROVIDER_NAME); 053 kg.init(keySize, new SecureRandom()); 054 return ByteUtils.toHexString(kg.generateKey().getEncoded()); 055 } 056 057 058 /** 059 * @Description:加密 060 */ 061 public static String encryptEcb(String hexKey, String paramStr, String charset) throws Exception { 062 String cipherText = ""; 063 if (null != paramStr && !"".equals(paramStr)) { 064 byte[] keyData = ByteUtils.fromHexString(hexKey); 065 charset = charset.trim(); 066 if (charset.length() <= 0) { 067 charset = ENCODING; 068 } 069 byte[] srcData = paramStr.getBytes(charset); 070 byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData); 071 cipherText = ByteUtils.toHexString(cipherArray); 072 } 073 return cipherText; 074 } 075 076 /** 077 * @Description:加密模式之ecb 078 */ 079 public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception { 080 Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key); 081 byte[] bs = cipher.doFinal(data); 082 return bs; 083 } 084 085 /** 086 * @Description:sm4解密 087 */ 088 public static String decryptEcb(String hexKey, String cipherText, String charset) throws Exception { 089 String decryptStr = ""; 090 byte[] keyData = ByteUtils.fromHexString(hexKey); 091 byte[] cipherData = ByteUtils.fromHexString(cipherText); 092 byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData); 093 charset = charset.trim(); 094 if (charset.length() <= 0) { 095 charset = ENCODING; 096 } 097 decryptStr = new String(srcData, charset); 098 return decryptStr; 099 } 100 101 /** 102 * @Description:解密 103 */ 104 public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception { 105 Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key); 106 return cipher.doFinal(cipherText); 107 } 108 109 /** 110 * @Description:密码校验 111 */ 112 public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception { 113 boolean flag = false; 114 byte[] keyData = ByteUtils.fromHexString(hexKey); 115 byte[] cipherData = ByteUtils.fromHexString(cipherText); 116 byte[] decryptData = decrypt_Ecb_Padding(keyData,cipherData); 117 byte[] srcData = paramStr.getBytes(ENCODING); 118 flag = Arrays.equals(decryptData,srcData); 119 return flag; 120 } 121 122// /** 123// * @Description:测试类 124// */ 125// public static void main(String[] args) { 126// try { 127// String keyByte = generateKey(DEFAULT_KEY_SIZE); 128// 129// String json = " 中国 人"; 130// // 自定义的32位16进制密钥 131// String key = generateKey(); 132// key = "a0710e8fa0856ee38c48d6d796356658"; 133// System.out.println(key); 134// String cipher = Sm4Utils.encryptEcb(key, json,ENCODING); 135// System.out.println(cipher); 136// System.out.println(Sm4Utils.verifyEcb(key, cipher, json)); 137// json = Sm4Utils.decryptEcb(key, cipher,ENCODING); 138// System.out.println(json); 139// } catch (Exception e) { 140// e.printStackTrace(); 141// } 142// } 143}