Java加密与解密的艺术~SM4实现
國產SM4加密解密算法概念介紹
SMS4算法是在國內廣泛使用的WAPI無線網絡標準中使用的加密算法,是一種32輪的迭代非平衡Feistel結構的分組加密算法,其密鑰長度和分組長度均為128。SMS4算法的加解密過程中使用的算法是完全相同的,唯一不同點在于該算法的解密密鑰是由它的加密密鑰進行逆序變換后得到的。
SMS4分組加密算法是中國無線標準中使用的分組加密算法,在2012年已經被國家商用密碼管理局確定為國家密碼行業標準,標準編號GM/T 0002-2012并且改名為SM4算法,與SM2橢圓曲線公鑰密碼算法,SM3密碼雜湊算法共同作為國家密碼的行業標準,在我國密碼行業中有著極其重要的位置。
SMS4算法的分組長度為128bit,密鑰長度也是128bit。加解密算法均采用32輪非平衡Feistel迭代結構,該結構最先出現在分組密碼LOKI的密鑰擴展算法中。SMS4通過32輪非線性迭代后加上一個反序變換,這樣只需要解密密鑰是加密密鑰的逆序,就能使得解密算法與加密算法保持一致。SMS4加解密算法的結構完全相同,只是在使用輪密鑰時解密密鑰是加密密鑰的逆序。
S盒是一種利用非線性變換構造的分組密碼的一個組件,主要是為了實現分組密碼過程中的混淆的特性和設計的。SMS4算法中的S盒在設計之初完全按照歐美分組密碼的設計標準進行,它采用的方法是能夠很好抵抗差值攻擊的仿射函數逆映射復合法。
SM4加密算法應用場景
SM4常用于政府系統的數據傳輸加密,比如當我們前端向后臺傳參數的時候,可以使用此算法。對參數的數據進行加密,然后后臺對加密的數據進行解密再存儲到數據庫中,保證數據傳輸過程中,不受泄露。
引入BouncyCastle組件支持
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.62</version> </dependency>SM4Utils
public class Sm4Utils {private static final String ENCODING = "UTF-8";public static final String ALGORIGTHM_NAME = "SM4";public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";public static final int DEFAULT_KEY_SIZE = 128;public Sm4Utils() {}static {Security.addProvider(new BouncyCastleProvider());}/*** @Description:生成ecb暗號*/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, ALGORIGTHM_NAME);cipher.init(mode, sm4Key);return cipher;}/*** @Description:自動生成密鑰*/public static byte[] generateKey() throws Exception {return generateKey(DEFAULT_KEY_SIZE);}public static byte[] generateKey(int keySize) throws Exception {KeyGenerator kg = KeyGenerator.getInstance(ALGORIGTHM_NAME, BouncyCastleProvider.PROVIDER_NAME);kg.init(keySize, new SecureRandom());return kg.generateKey().getEncoded();}/*** @Description:加密*/public static String encryptEcb(String hexKey, String paramStr, String charset) throws Exception {String cipherText = "";if (null != paramStr && !"".equals(paramStr)) {byte[] keyData = ByteUtils.fromHexString(hexKey);charset = charset.trim();if (charset.length() <= 0) {charset = ENCODING;}byte[] srcData = paramStr.getBytes(charset);byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);cipherText = ByteUtils.toHexString(cipherArray);}return cipherText;}/*** @Description:加密模式之ecb*/public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);byte[] bs = cipher.doFinal(data);return bs;}/*** @Description:sm4解密*/public static String decryptEcb(String hexKey, String cipherText, String charset) throws Exception {String decryptStr = "";byte[] keyData = ByteUtils.fromHexString(hexKey);byte[] cipherData = ByteUtils.fromHexString(cipherText);byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);charset = charset.trim();if (charset.length() <= 0) {charset = ENCODING;}decryptStr = new String(srcData, charset);return decryptStr;}/*** @Description:解密*/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);}/*** @Description:密碼校驗*/public static boolean verifyEcb(String hexKey,String cipherText,String paramStr) throws Exception {boolean flag = false;byte[] keyData = ByteUtils.fromHexString(hexKey);byte[] cipherData = ByteUtils.fromHexString(cipherText);byte[] decryptData = decrypt_Ecb_Padding(keyData,cipherData);byte[] srcData = paramStr.getBytes(ENCODING);flag = Arrays.equals(decryptData,srcData);return flag;}/*** @Description:測試類*/public static void main(String[] args) {try {String json = "{\"name\":\"color\",\"sex\":\"man\"}";// 自定義的32位16進制密鑰String key = "cc9368581322479ebf3e79348a2757d9";String cipher = Sm4Utils.encryptEcb(key, json,ENCODING);System.out.println(cipher);System.out.println(Sm4Utils.verifyEcb(key, cipher, json));json = Sm4Utils.decryptEcb(key, cipher,ENCODING);System.out.println(json);} catch (Exception e) {e.printStackTrace();}}}總結
以上是生活随笔為你收集整理的Java加密与解密的艺术~SM4实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言assign用法,object-c
- 下一篇: 【itext学习之路】--5.对pdf进