前一阵子做的项目,越来越多的金融类应用使用国密算法进行加解密的运算。
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。
JAVA代码:Util:
1 import javax.crypto.SecretKey; 2 import javax.crypto.SecretKeyFactory; 3 import javax.crypto.spec.PBEKeySpec; 4 import javax.crypto.spec.SecretKeySpec; 5 import java.math.BigInteger; 6 import java.security.NoSuchAlgorithmException; 7 import java.security.SecureRandom; 8 import java.security.spec.InvalidKeySpecException; 9 import java.security.spec.KeySpec; 10 11 public class Util { 12 public static final byte MAX_VALUE = -1; 13 public static byte[] hexToByte(String arg8) { 14 if(arg8.length() % 2 == 0) { 15 char[] v0 = arg8.toCharArray(); 16 byte[] v1 = new byte[arg8.length() / 2]; 17 int v2 = 0; 18 int v3 = 0; 19 int v4 = arg8.length(); 20 while(v2 < v4) { 21 StringBuilder v5 = new StringBuilder(); 22 v5.append(""); 23 int v6 = v2 + 1; 24 v5.append(v0[v2]); 25 v5.append(v0[v6]); 26 v1[v3] = new Integer(Integer.parseInt(v5.toString(), 16) & 255).byteValue(); 27 v2 = v6 + 1; 28 ++v3; 29 } 30 31 return v1; 32 } 33 throw new IllegalArgumentException(); 34 } 35 public static String byteToHex(byte[] arg5) { 36 if(arg5 != null) { 37 String v0 = ""; 38 int v2; 39 for(v2 = 0; v2 < arg5.length; ++v2) { 40 String v1 = Integer.toHexString(arg5[v2] & 255); 41 v0 = v1.length() == 1 ? v0 + "0" + v1 : v0 + v1; 42 } 43 44 return v0.toUpperCase(); 45 } 46 throw new IllegalArgumentException("Argument b ( byte array ) is null! "); 47 } 48 49 public static byte[] byteConvert32Bytes(BigInteger arg5) { 50 byte[] v0 = null; 51 if(arg5 == null) { 52 return v0; 53 } 54 55 int v4 = 32; 56 if(arg5.toByteArray().length == 33) { 57 v0 = new byte[v4]; 58 System.arraycopy(arg5.toByteArray(), 1, v0, 0, v4); 59 } 60 else if(arg5.toByteArray().length == v4) { 61 v0 = arg5.toByteArray(); 62 } 63 else { 64 v0 = new byte[v4]; 65 int v1; 66 for(v1 = 0; v1 < 32 - arg5.toByteArray().length; ++v1) { 67 v0[v1] = 0; 68 } 69 70 System.arraycopy(arg5.toByteArray(), 0, v0, v4 - arg5.toByteArray().length, arg5.toByteArray().length); 71 } 72 73 return v0; 74 } 75 76 public static byte[] hexStringToBytes(String arg7) { 77 if(arg7 != null) { 78 if(arg7.equals("")) { 79 } 80 else { 81 arg7 = arg7.toUpperCase(); 82 int v0 = arg7.length() / 2; 83 char[] v1 = arg7.toCharArray(); 84 byte[] v2 = new byte[v0]; 85 int v3; 86 for(v3 = 0; v3 < v0; ++v3) { 87 int v4 = v3 * 2; 88 v2[v3] = ((byte)(Util.charToByte(v1[v4]) << 4 | Util.charToByte(v1[v4 + 1]))); 89 } 90 91 return v2; 92 } 93 } 94 95 return null; 96 } 97 98 public static byte charToByte(char arg1) { 99 return ((byte)"0123456789ABCDEF".indexOf(arg1)); 100 } 101 102 }
SM2:
1 import org.bouncycastle.crypto.generators.ECKeyPairGenerator; 2 import org.bouncycastle.crypto.params.ECDomainParameters; 3 import org.bouncycastle.crypto.params.ECKeyGenerationParameters; 4 import org.bouncycastle.math.ec.ECCurve; 5 import org.bouncycastle.math.ec.ECFieldElement; 6 import org.bouncycastle.math.ec.ECPoint; 7 8 import java.math.BigInteger; 9 import java.security.SecureRandom; 10 11 public class SM2 { 12 public static String[] ecc_param = {"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"}; 13 public final BigInteger ecc_p = new BigInteger(ecc_param[0], 16); 14 public final BigInteger ecc_a = new BigInteger(ecc_param[1], 16); 15 public final BigInteger ecc_b = new BigInteger(ecc_param[2], 16); 16 public final BigInteger ecc_n = new BigInteger(ecc_param[3], 16); 17 public final BigInteger ecc_gx = new BigInteger(ecc_param[4], 16); 18 public final BigInteger ecc_gy = new BigInteger(ecc_param[5], 16); 19 public final ECFieldElement ecc_gx_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gx); 20 public final ECFieldElement ecc_gy_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gy); 21 public final ECCurve ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b); 22 public final ECPoint ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement); 23 public final ECDomainParameters ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n); 24 public final ECKeyPairGenerator ecc_key_pair_generator; 25 26 public static SM2 Instance() { 27 return new SM2(); 28 } 29 30 public SM2() { 31 ECKeyGenerationParameters ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom()); 32 this.ecc_key_pair_generator = new ECKeyPairGenerator(); 33 this.ecc_key_pair_generator.init(ecc_ecgenparam); 34 } 35 }
SM2Util:
1 import org.bouncycastle.crypto.AsymmetricCipherKeyPair; 2 import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 3 import org.bouncycastle.crypto.params.ECPrivateKeyParameters; 4 import org.bouncycastle.crypto.params.ECPublicKeyParameters; 5 import org.bouncycastle.math.ec.ECPoint; 6 7 import java.io.IOException; 8 import java.math.BigInteger; 9 10 public class SM2Util { 11 public static final String PUBLIC_KEY = "你的公钥1"; 12 public static final String PUBLIC_KEY_2 = "你的公钥2"; 13 public static String encrypt(String key, String mes) { 14 byte[] arg9 = mes.getBytes(); 15 byte[] arg8 = Util.hexToByte(key); 16 String v0 = null; 17 if(arg8 != null) { 18 if(arg8.length == 0) { 19 } 20 else { 21 if(arg9 != null) { 22 if(arg9.length == 0) { 23 } 24 else { 25 byte[] v0_1 = new byte[arg9.length]; 26 System.arraycopy(arg9, 0, v0_1, 0, arg9.length); 27 Cipher v1 = new Cipher(); 28 SM2 v2 = SM2.Instance(); 29 ECPoint v4 = v1.Init_enc(v2, v2.ecc_curve.decodePoint(arg8)); 30 v1.Encrypt(v0_1); 31 byte[] v5 = new byte[32]; 32 v1.Dofinal(v5); 33 return Util.byteToHex(v4.getEncoded()) + Util.byteToHex(v5) + Util.byteToHex(v0_1); 34 } 35 } 36 return v0; 37 } 38 } 39 return v0; 40 } 41 42 public static String decrypt(String key, String mes) throws IOException { 43 byte[] arg9 = Util.hexToByte(key); 44 byte[] arg10 = Util.hexToByte(mes); 45 byte[] v0 = null; 46 if(arg9 != null) { 47 if(arg9.length == 0) { 48 } 49 else { 50 if(arg10 != null) { 51 if(arg10.length == 0) { 52 } 53 else { 54 String v0_1 = Util.byteToHex(arg10); 55 byte[] v1 = Util.hexToByte(v0_1.substring(0, 130)); 56 int v3 = arg10.length - 97; 57 byte[] v2 = Util.hexToByte(v0_1.substring(130, 194)); 58 byte[] v4 = Util.hexToByte(v0_1.substring(194, v3 * 2 + 194)); 59 SM2 v5 = SM2.Instance(); 60 BigInteger v6 = new BigInteger(1, arg9); 61 ECPoint v7 = v5.ecc_curve.decodePoint(v1); 62 Cipher v8 = new Cipher(); 63 v8.Init_dec(v6, v7); 64 v8.Decrypt(v4); 65 v8.Dofinal(v2); 66 return new String(v4); 67 } 68 } 69 70 return new String(v0); 71 } 72 } 73 return new String(v0); 74 } 75 76 // public static SM2KeyVO generateKeyPair() { 77 // AsymmetricCipherKeyPair v1; 78 // SM2 v0 = SM2.Instance(); 79 // while(true) { 80 // v1 = v0.ecc_key_pair_generator.generateKeyPair(); 81 // if(v1.getPrivate().getD().toByteArray().length == 32) { 82 // break; 83 // } 84 // } 85 // 86 // AsymmetricKeyParameter v2 = v1.getPrivate(); 87 // AsymmetricKeyParameter v3 = v1.getPublic(); 88 // BigInteger v4 = ((ECPrivateKeyParameters)v2).getD(); 89 // ECPoint v5 = ((ECPublicKeyParameters)v3).getQ(); 90 // SM2KeyVO v6 = new SM2KeyVO(); 91 // v6.setPublicKey(v5); 92 // v6.setPrivateKey(v4); 93 // return v6; 94 // } 95 96 }
SM2KeyVO:
1 import org.bouncycastle.math.ec.ECPoint; 2 3 import java.math.BigInteger; 4 5 public class SM2KeyVO { 6 BigInteger privateKey; 7 ECPoint publicKey; 8 9 public String getPriHexInSoft() { 10 return Util.byteToHex(this.privateKey.toByteArray()); 11 } 12 13 public BigInteger getPrivateKey() { 14 return this.privateKey; 15 } 16 17 public String getPubHexInSoft() { 18 return Util.byteToHex(this.publicKey.getEncoded()); 19 } 20 21 public ECPoint getPublicKey() { 22 return this.publicKey; 23 } 24 25 public void setPrivateKey(BigInteger arg1) { 26 this.privateKey = arg1; 27 } 28 29 public void setPublicKey(ECPoint arg1) { 30 this.publicKey = arg1; 31 } 32 }
SM3Util:
1 import org.bouncycastle.crypto.digests.SM3Digest; 2 import org.bouncycastle.util.encoders.Hex; 3 4 public class SM3Util { 5 public static String sm3(String arg5) { 6 byte[] v0 = new byte[32]; 7 byte[] v1 = arg5.getBytes(); 8 SM3Digest v2 = new SM3Digest(); 9 v2.update(v1, 0, v1.length); 10 v2.doFinal(v0, 0); 11 return new String(Hex.encode(v0)).toUpperCase(); 12 } 13 }
SM4:
1 import java.io.ByteArrayInputStream; 2 import java.io.ByteArrayOutputStream; 3 4 public class SM4 { 5 public static final int[] CK = new int[]{462357, 472066609, 943670861, 1415275113, 1886879365, -1936483679, -1464879427, -993275175, -521670923, -66909679, 404694573, 876298825, 1347903077, 1819507329, -2003855715, -1532251463, -1060647211, -589042959, -117504499, 337322537, 808926789, 1280531041, 1752135293, -2071227751, -1599623499, -1128019247, -656414995, -184876535, 269950501, 741554753, 1213159005, 1684763257}; 6 public static final int[] FK = new int[]{-1548633402, 1453994832, 1736282519, -1301273892}; 7 public static final int SM4_DECRYPT = 0; 8 public static final int SM4_ENCRYPT = 1; 9 public static final byte[] SboxTable = new byte[]{-42, -112, -23, -2, -52, -31, 61, -73, 22, -74, 20, -62, 40, -5, 44, 5, 43, 103, -102, 118, 42, -66, 4, -61, -86, 68, 19, 38, 73, -122, 6, -103, -100, 66, 80, -12, -111, -17, -104, 122, 51, 84, 11, 67, -19, -49, -84, 98, -28, -77, 28, -87, -55, 8, -24, -107, -128, -33, -108, -6, 117, -113, 63, -90, 71, 7, -89, -4, -13, 115, 23, -70, -125, 89, 60, 25, -26, -123, 79, -88, 104, 107, -127, -78, 113, 100, -38, -117, -8, -21, 15, 75, 112, 86, -99, 53, 30, 36, 14, 94, 99, 88, -47, -94, 37, 34, 124, 59, 1, 33, 120, -121, -44, 0, 70, 87, -97, -45, 39, 82, 76, 54, 2, -25, -96, -60, -56, -98, -22, -65, -118, -46, 64, -57, 56, -75, -93, -9, -14, -50, -7, 97, 21, -95, -32, -82, 93, -92, -101, 52, 26, 85, -83, -109, 50, 48, -11, -116, -79, -29, 29, -10, -30, 46, -126, 102, -54, 96, -64, 41, 35, -85, 13, 83, 78, 111, -43, -37, 55, 69, -34, -3, -114, 47, 3, -1, 106, 114, 109, 108, 91, 81, -115, 27, -81, -110, -69, -35, -68, 127, 17, -39, 92, 65, 31, 16, 90, -40, 10, -63, 49, -120, -91, -51, 123, -67, 45, 116, -48, 18, -72, -27, -76, -80, -119, 105, -105, 74, 12, -106, 119, 126, 101, -71, -15, 9, -59, 110, -58, -124, 24, -16, 125, -20, 58, -36, 77, 32, 121, -18, 95, 62, -41, -53, 57, 72}; 10 11 public SM4() { 12 super(); 13 } 14 15 private long GET_ULONG_BE(byte[] arg7, int arg8) { 16 return (((long)(arg7[arg8] & 255))) << 24 | (((long)((arg7[arg8 + 1] & 255) << 16))) | (((long)((arg7[arg8 + 2] & 255) << 8))) | (((long)(arg7[arg8 + 3] & 255))) & 4294967295L; 17 } 18 19 private void PUT_ULONG_BE(long arg7, byte[] arg9, int arg10) { 20 arg9[arg10] = ((byte)(((int)(arg7 >> 24 & 255)))); 21 arg9[arg10 + 1] = ((byte)(((int)(arg7 >> 16 & 255)))); 22 arg9[arg10 + 2] = ((byte)(((int)(arg7 >> 8 & 255)))); 23 arg9[arg10 + 3] = ((byte)(((int)(arg7 & 255)))); 24 } 25 26 private long ROTL(long arg5, int arg7) { 27 return this.SHL(arg5, arg7) | arg5 >> 32 - arg7; 28 } 29 30 private long SHL(long arg3, int arg5) { 31 return (-1 & arg3) << arg5; 32 } 33 34 private void SWAP(long[] arg5, int arg6) { 35 long v0 = arg5[arg6]; 36 arg5[arg6] = arg5[31 - arg6]; 37 arg5[31 - arg6] = v0; 38 } 39 40 private byte[] padding(byte[] arg6, int arg7) { 41 int v1; 42 byte[] v0 = null; 43 if(arg6 == null) { 44 return v0; 45 } 46 47 if(arg7 == 1) { 48 v1 = 16 - arg6.length % 16; 49 v0 = new byte[arg6.length + v1]; 50 System.arraycopy(arg6, 0, v0, 0, arg6.length); 51 int v2; 52 for(v2 = 0; v2 < v1; ++v2) { 53 v0[arg6.length + v2] = ((byte)v1); 54 } 55 } 56 else { 57 v1 = arg6[arg6.length - 1]; 58 v0 = new byte[arg6.length - v1]; 59 System.arraycopy(arg6, 0, v0, 0, arg6.length - v1); 60 } 61 62 return v0; 63 } 64 65 private long sm4CalciRK(long arg11) { 66 byte[] v5 = new byte[4]; 67 byte[] v4 = new byte[4]; 68 this.PUT_ULONG_BE(arg11, v5, 0); 69 v4[0] = this.sm4Sbox(v5[0]); 70 v4[1] = this.sm4Sbox(v5[1]); 71 v4[2] = this.sm4Sbox(v5[2]); 72 v4[3] = this.sm4Sbox(v5[3]); 73 long v0 = this.GET_ULONG_BE(v4, 0); 74 return this.ROTL(v0, 13) ^ v0 ^ this.ROTL(v0, 23); 75 } 76 77 private long sm4F(long arg3, long arg5, long arg7, long arg9, long arg11) { 78 return this.sm4Lt(arg5 ^ arg7 ^ arg9 ^ arg11) ^ arg3; 79 } 80 81 private long sm4Lt(long arg11) { 82 byte[] v5 = new byte[4]; 83 byte[] v4 = new byte[4]; 84 this.PUT_ULONG_BE(arg11, v5, 0); 85 v4[0] = this.sm4Sbox(v5[0]); 86 v4[1] = this.sm4Sbox(v5[1]); 87 v4[2] = this.sm4Sbox(v5[2]); 88 v4[3] = this.sm4Sbox(v5[3]); 89 long v0 = this.GET_ULONG_BE(v4, 0); 90 return this.ROTL(v0, 2) ^ v0 ^ this.ROTL(v0, 10) ^ this.ROTL(v0, 18) ^ this.ROTL(v0, 24); 91 } 92 93 private byte sm4Sbox(byte arg3) { 94 return SM4.SboxTable[arg3 & 255]; 95 } 96 97 public byte[] sm4_crypt_cbc(SM4_Context arg13, byte[] arg14, byte[] arg15) throws Exception { 98 byte[] v8; 99 byte[] v6; 100 byte[] v2; 101 if(arg14 != null) { 102 int v1 = 16; 103 if(arg14.length == v1) { 104 if(arg15 != null) { 105 if((arg13.isPadding) && arg13.mode == 1) { 106 arg15 = this.padding(arg15, 1); 107 } 108 109 int v3 = arg15.length; 110 ByteArrayInputStream v4 = new ByteArrayInputStream(arg15); 111 ByteArrayOutputStream v5 = new ByteArrayOutputStream(); 112 if(arg13.mode == 1) { 113 while(v3 > 0) { 114 v2 = new byte[v1]; 115 v6 = new byte[v1]; 116 v8 = new byte[v1]; 117 v4.read(v2); 118 int v0; 119 for(v0 = 0; v0 < v1; ++v0) { 120 v6[v0] = ((byte)(v2[v0] ^ arg14[v0])); 121 } 122 123 this.sm4_one_round(arg13.sk, v6, v8); 124 System.arraycopy(v8, 0, arg14, 0, v1); 125 v5.write(v8); 126 v3 += -16; 127 } 128 } 129 else { 130 v2 = new byte[v1]; 131 while(v3 > 0) { 132 v6 = new byte[v1]; 133 v8 = new byte[v1]; 134 byte[] v9 = new byte[v1]; 135 v4.read(v6); 136 System.arraycopy(v6, 0, v2, 0, v1); 137 this.sm4_one_round(arg13.sk, v6, v8); 138 int v0; 139 for(v0 = 0; v0 < v1; ++v0) { 140 v9[v0] = ((byte)(v8[v0] ^ arg14[v0])); 141 } 142 143 System.arraycopy(v2, 0, arg14, 0, v1); 144 v5.write(v9); 145 v3 += -16; 146 } 147 } 148 149 byte[] v1_1 = v5.toByteArray(); 150 if((arg13.isPadding) && arg13.mode == 0) { 151 v1_1 = this.padding(v1_1, 0); 152 } 153 154 v4.close(); 155 v5.close(); 156 return v1_1; 157 } 158 else { 159 throw new Exception("input is null!"); 160 } 161 } 162 } 163 164 throw new Exception("iv error!"); 165 } 166 167 public byte[] sm4_crypt_ecb(SM4_Context arg7, byte[] arg8) throws Exception { 168 byte[] v3; 169 if(arg8 != null) { 170 if((arg7.isPadding) && arg7.mode == 1) { 171 arg8 = this.padding(arg8, 1); 172 } 173 174 int v0 = arg8.length; 175 ByteArrayInputStream v1 = new ByteArrayInputStream(arg8); 176 ByteArrayOutputStream v2 = new ByteArrayOutputStream(); 177 while(v0 > 0) { 178 byte[] v4 = new byte[16]; 179 v3 = new byte[16]; 180 v1.read(v4); 181 this.sm4_one_round(arg7.sk, v4, v3); 182 v2.write(v3); 183 v0 += -16; 184 } 185 186 v3 = v2.toByteArray(); 187 if((arg7.isPadding) && arg7.mode == 0) { 188 v3 = this.padding(v3, 0); 189 } 190 191 v1.close(); 192 v2.close(); 193 return v3; 194 } 195 196 throw new Exception("input is null!"); 197 } 198 199 private void sm4_one_round(long[] arg23, byte[] arg24, byte[] arg25) { 200 int v0; 201 SM4 v11 = this; 202 byte[] v13 = arg25; 203 long[] v14 = new long[36]; 204 v14[0] = v11.GET_ULONG_BE(arg24, 0); 205 v14[1] = v11.GET_ULONG_BE(arg24, 4); 206 v14[2] = v11.GET_ULONG_BE(arg24, 8); 207 v14[3] = v11.GET_ULONG_BE(arg24, 12); 208 int v8; 209 for(v8 = 0; true; ++v8) { 210 v0 = 32; 211 if(v8 >= v0) { 212 break; 213 } 214 215 v14[v8 + 4] = this.sm4F(v14[v8], v14[v8 + 1], v14[v8 + 2], v14[v8 + 3], arg23[v8]); 216 } 217 218 v11.PUT_ULONG_BE(v14[35], v13, 0); 219 v11.PUT_ULONG_BE(v14[34], v13, 4); 220 v11.PUT_ULONG_BE(v14[33], v13, 8); 221 v11.PUT_ULONG_BE(v14[v0], v13, 12); 222 } 223 224 private void sm4_setkey(long[] arg13, byte[] arg14) { 225 long[] v1 = new long[4]; 226 long[] v2 = new long[36]; 227 int v3 = 0; 228 v1[0] = this.GET_ULONG_BE(arg14, 0); 229 v1[1] = this.GET_ULONG_BE(arg14, 4); 230 v1[2] = this.GET_ULONG_BE(arg14, 8); 231 v1[3] = this.GET_ULONG_BE(arg14, 12); 232 long v5 = v1[0]; 233 int[] v9 = SM4.FK; 234 v2[0] = v5 ^ (((long)v9[0])); 235 v2[1] = v1[1] ^ (((long)v9[1])); 236 v2[2] = v1[2] ^ (((long)v9[2])); 237 v2[3] = v1[3] ^ (((long)v9[3])); 238 while(v3 < 32) { 239 v2[v3 + 4] = v2[v3] ^ this.sm4CalciRK(v2[v3 + 1] ^ v2[v3 + 2] ^ v2[v3 + 3] ^ (((long)SM4.CK[v3]))); 240 arg13[v3] = v2[v3 + 4]; 241 ++v3; 242 } 243 } 244 245 public void sm4_setkey_dec(SM4_Context arg4, byte[] arg5) throws Exception { 246 if(arg4 != null) { 247 if(arg5 != null) { 248 int v1 = 16; 249 if(arg5.length == v1) { 250 arg4.mode = 0; 251 this.sm4_setkey(arg4.sk, arg5); 252 int v0; 253 for(v0 = 0; v0 < v1; ++v0) { 254 this.SWAP(arg4.sk, v0); 255 } 256 257 return; 258 } 259 } 260 261 throw new Exception("key error!"); 262 } 263 264 throw new Exception("ctx is null!"); 265 } 266 267 public void sm4_setkey_enc(SM4_Context arg3, byte[] arg4) throws Exception { 268 if(arg3 != null) { 269 if(arg4 != null && arg4.length == 16) { 270 arg3.mode = 1; 271 this.sm4_setkey(arg3.sk, arg4); 272 return; 273 } 274 275 throw new Exception("key error!"); 276 } 277 278 throw new Exception("ctx is null!"); 279 } 280 }
SM4_Context:
1 public class SM4_Context { 2 public boolean isPadding; 3 public int mode; 4 public long[] sk; 5 6 public SM4_Context() { 7 super(); 8 this.mode = 1; 9 this.isPadding = true; 10 this.sk = new long[32]; 11 } 12 }
SM4Util:
1 import org.apache.commons.codec.binary.Base64; 2 3 import java.io.IOException; 4 import java.io.PrintStream; 5 import java.util.regex.Pattern; 6 7 public class SM4Utils { 8 public static final String KEY = "你的key"; 9 public static final String IV = "你的IV"; 10 public boolean hexString; 11 public String iv; 12 public String secretKey; 13 14 public SM4Utils() { 15 super(); 16 this.secretKey = ""; 17 this.iv = ""; 18 this.hexString = false; 19 } 20 21 public static String sm4Decrypt(String mes) { 22 SM4Utils v0 = new SM4Utils(); 23 v0.secretKey = KEY; 24 v0.iv = IV; 25 v0.hexString = true; 26 return v0.decryptData_CBC(mes); 27 } 28 29 public static String sm4Encrypt(String mes) { 30 SM4Utils v0 = new SM4Utils(); 31 v0.secretKey = KEY; 32 v0.iv = IV; 33 v0.hexString = true; 34 return v0.encryptData_CBC(mes); 35 } 36 37 public String decryptData_CBC(String arg9) { 38 byte[] v3; 39 byte[] v2; 40 try { 41 arg9 = Base64.encodeBase64String(Util.hexToByte(arg9)); 42 if(arg9 != null && arg9.trim().length() > 0) { 43 arg9 = Pattern.compile("\\s*|\t|\r|\n").matcher(((CharSequence)arg9)).replaceAll(""); 44 } 45 46 SM4_Context v1 = new SM4_Context(); 47 v1.isPadding = true; 48 v1.mode = 0; 49 if(this.hexString) { 50 v2 = Util.hexStringToBytes(this.secretKey); 51 v3 = Util.hexStringToBytes(this.iv); 52 } 53 else { 54 v2 = this.secretKey.getBytes(); 55 v3 = this.iv.getBytes(); 56 } 57 58 SM4 v4 = new SM4(); 59 v4.sm4_setkey_dec(v1, v2); 60 return new String(v4.sm4_crypt_cbc(v1, v3, Base64.decodeBase64(arg9)), "UTF-8"); 61 } 62 catch(Exception v0) { 63 v0.printStackTrace(); 64 return null; 65 } 66 } 67 68 public String encryptData_CBC(String arg7) { 69 byte[] v2; 70 byte[] v1; 71 try { 72 SM4_Context v0_1 = new SM4_Context(); 73 v0_1.isPadding = true; 74 v0_1.mode = 1; 75 if(this.hexString) { 76 v1 = Util.hexStringToBytes(this.secretKey); 77 v2 = Util.hexStringToBytes(this.iv); 78 } 79 else { 80 v1 = this.secretKey.getBytes(); 81 v2 = this.iv.getBytes(); 82 } 83 84 SM4 v3 = new SM4(); 85 v3.sm4_setkey_enc(v0_1, v1); 86 return Util.byteToHex(v3.sm4_crypt_cbc(v0_1, v2, arg7.getBytes("UTF-8"))); 87 } 88 catch(Exception v0) { 89 v0.printStackTrace(); 90 return null; 91 } 92 } 93 94 public String decryptData_ECB(String arg8) { 95 try { 96 arg8 = Base64.encodeBase64String(Util.hexToByte(arg8)); 97 if(arg8 != null && arg8.trim().length() > 0) { 98 arg8 = Pattern.compile("\\s*|\t|\r|\n").matcher(((CharSequence)arg8)).replaceAll(""); 99 } 100 101 SM4_Context v1 = new SM4_Context(); 102 v1.isPadding = true; 103 v1.mode = 0; 104 byte[] v2 = this.hexString ? Util.hexStringToBytes(this.secretKey) : this.secretKey.getBytes(); 105 SM4 v3 = new SM4(); 106 v3.sm4_setkey_dec(v1, v2); 107 return new String(v3.sm4_crypt_ecb(v1, Base64.decodeBase64(arg8)), "UTF-8"); 108 } 109 catch(Exception v0) { 110 v0.printStackTrace(); 111 return null; 112 } 113 } 114 115 public String encryptData_ECB(String arg6) { 116 try { 117 SM4_Context v0_1 = new SM4_Context(); 118 v0_1.isPadding = true; 119 v0_1.mode = 1; 120 byte[] v1 = this.hexString ? Util.hexStringToBytes(this.secretKey) : Util.hexStringToBytes(this.secretKey); 121 SM4 v2 = new SM4(); 122 v2.sm4_setkey_enc(v0_1, v1); 123 return Util.byteToHex(v2.sm4_crypt_ecb(v0_1, arg6.getBytes("UTF-8"))); 124 } 125 catch(Exception v0) { 126 v0.printStackTrace(); 127 return null; 128 } 129 } 130 131 }
需要导入的jar:
链接:https://pan.baidu.com/s/1ywPfsQvWAyN8UHRXoAHodw 密码:x1gy
来源:https://www.cnblogs.com/CYCLearning/p/12187688.html