├── README.md └── SMS4_Decrypt ├── SMS4_Decrypt.iml ├── pom.xml ├── src └── main │ └── java │ ├── Main.java │ └── com │ ├── common │ └── utils │ │ └── SMS4.java │ └── exception │ └── CommonException.java └── target ├── SMS4_Decrypt-1.0-SNAPSHOT-jar-with-dependencies.jar ├── SMS4_Decrypt-1.0-SNAPSHOT.jar └── classes ├── Main.class └── com ├── common └── utils │ └── SMS4.class └── exception └── CommonException.class /README.md: -------------------------------------------------------------------------------- 1 | # SMS4_Decrypt 2 | 3 | ### 0x01 简介 4 | 5 | SMS4算法是在国内广泛使用的WAPI无线网络标准中使用的加密算法,是一种32轮的迭代非平衡Feistel结构的分组加密算法,其密钥长度和分组长度均为128。 6 | 7 | SMS4算法的加解密过程中使用的算法是完全相同的,唯一不同点在于该算法的解密密钥是由它的加密密钥进行逆序变换后得到的。 8 | 9 | https://baike.baidu.com/item/SMS4%E7%AE%97%E6%B3%95/16858974 10 | 11 | ### Usage: 12 | 13 | `change Main.java set SMS4_KEY` 14 | 15 | `len(SMS4_KEY) = 16` 16 | 17 | e.g. 18 | 19 | `java -jar SMS4_Decrypt-1.0-SNAPSHOT-jar-with-dependencies.jar ` 20 | 21 | ``` 22 | 23 | 24 | [+] SMS4 Decrypt 25 | [+] Example: 1D7114B6968BF8208DD94A4DECE634CD 26 | 27 | [+] Input SMS4 Password= 1D7114B6968BF8208DD94A4DECE634CD 28 | [+] Passwd Length=32 29 | [+] 明文密码= Jas502n 30 | 31 | [+] Input SMS4 Password= 32 | 33 | ``` 34 | 35 | 打包jar 36 | 37 | `mvn install` 38 | -------------------------------------------------------------------------------- /SMS4_Decrypt/SMS4_Decrypt.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SMS4_Decrypt/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | SMS4_Decrypt 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | commons-lang 15 | commons-lang 16 | 2.4 17 | 18 | 19 | 20 | 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-assembly-plugin 25 | 26 | 27 | 28 | package 29 | 30 | single 31 | 32 | 33 | 34 | 35 | 36 | 37 | jar-with-dependencies 38 | 39 | 40 | 41 | true 42 | lib/ 43 | Main 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /SMS4_Decrypt/src/main/java/Main.java: -------------------------------------------------------------------------------- 1 | import com.common.utils.SMS4; 2 | 3 | import java.util.Scanner; 4 | 5 | 6 | public class Main { 7 | public static String SMS4Decrypt(String data) { 8 | // byte[] SMS4_KEY = new byte[]{}; 9 | byte[] SMS4_KEY = "12345678abcdefgh".getBytes(); 10 | String passwd = SMS4.decodeSMS4(data, SMS4_KEY); 11 | return passwd; 12 | } 13 | public static String SMS4Eecrypt(String data) { 14 | // byte[] SMS4_KEY = new byte[]{}; 15 | byte[] SMS4_KEY = "12345678abcdefgh".getBytes(); 16 | // SMS4_KEY length= 16 17 | 18 | String passwd = SMS4.encodeSMS4(data, SMS4_KEY); 19 | return passwd; 20 | } 21 | 22 | public static void main(String[] args) { 23 | // System.out.println(SMS4Eecrypt("Jas502n")); 24 | 25 | Scanner sc = new Scanner(System.in); 26 | System.out.println("\n[+] SMS4 Decrypt"); 27 | 28 | System.out.println("[+] Example: 1D7114B6968BF8208DD94A4DECE634CD\n"); 29 | while (true) { 30 | System.out.print("[+] Input SMS4 Password= "); 31 | String passwd = sc.nextLine(); 32 | System.out.println("[+] Passwd Length=" + passwd.length()); 33 | System.out.println("[+] 明文密码= " + SMS4Decrypt(passwd)); 34 | System.out.println(); 35 | 36 | } 37 | 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /SMS4_Decrypt/src/main/java/com/common/utils/SMS4.java: -------------------------------------------------------------------------------- 1 | package com.common.utils; 2 | 3 | import java.util.Arrays; 4 | import org.apache.commons.lang.StringUtils; 5 | import com.exception.CommonException; 6 | 7 | public class SMS4 { 8 | private static final int ENCRYPT = 1; 9 | private static final int DECRYPT = 0; 10 | public static final int ROUND = 32; 11 | private static final int BLOCK = 16; 12 | private byte[] Sbox = 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}; 13 | private 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}; 14 | 15 | private int Rotl(int x, int y) { 16 | return x << y | x >>> 32 - y; 17 | } 18 | 19 | private int ByteSub(int A) { 20 | return (this.Sbox[A >>> 24 & 255] & 255) << 24 | (this.Sbox[A >>> 16 & 255] & 255) << 16 | (this.Sbox[A >>> 8 & 255] & 255) << 8 | this.Sbox[A & 255] & 255; 21 | } 22 | 23 | private int L1(int B) { 24 | return B ^ this.Rotl(B, 2) ^ this.Rotl(B, 10) ^ this.Rotl(B, 18) ^ this.Rotl(B, 24); 25 | } 26 | 27 | private int L2(int B) { 28 | return B ^ this.Rotl(B, 13) ^ this.Rotl(B, 23); 29 | } 30 | 31 | void SMS4Crypt(byte[] Input, byte[] Output, int[] rk) { 32 | int[] x = new int[4]; 33 | int[] tmp = new int[4]; 34 | 35 | int j; 36 | for(j = 0; j < 4; ++j) { 37 | tmp[0] = Input[0 + 4 * j] & 255; 38 | tmp[1] = Input[1 + 4 * j] & 255; 39 | tmp[2] = Input[2 + 4 * j] & 255; 40 | tmp[3] = Input[3 + 4 * j] & 255; 41 | x[j] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3]; 42 | } 43 | 44 | for(int r = 0; r < 32; r += 4) { 45 | int mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0]; 46 | mid = this.ByteSub(mid); 47 | x[0] ^= this.L1(mid); 48 | mid = x[2] ^ x[3] ^ x[0] ^ rk[r + 1]; 49 | mid = this.ByteSub(mid); 50 | x[1] ^= this.L1(mid); 51 | mid = x[3] ^ x[0] ^ x[1] ^ rk[r + 2]; 52 | mid = this.ByteSub(mid); 53 | x[2] ^= this.L1(mid); 54 | mid = x[0] ^ x[1] ^ x[2] ^ rk[r + 3]; 55 | mid = this.ByteSub(mid); 56 | x[3] ^= this.L1(mid); 57 | } 58 | 59 | for(j = 0; j < 16; j += 4) { 60 | Output[j] = (byte)(x[3 - j / 4] >>> 24 & 255); 61 | Output[j + 1] = (byte)(x[3 - j / 4] >>> 16 & 255); 62 | Output[j + 2] = (byte)(x[3 - j / 4] >>> 8 & 255); 63 | Output[j + 3] = (byte)(x[3 - j / 4] & 255); 64 | } 65 | 66 | } 67 | 68 | private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) { 69 | int[] x = new int[4]; 70 | int[] tmp = new int[4]; 71 | 72 | for(int i = 0; i < 4; ++i) { 73 | tmp[0] = Key[0 + 4 * i] & 255; 74 | tmp[1] = Key[1 + 4 * i] & 255; 75 | tmp[2] = Key[2 + 4 * i] & 255; 76 | tmp[3] = Key[3 + 4 * i] & 255; 77 | x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3]; 78 | } 79 | 80 | x[0] ^= -1548633402; 81 | x[1] ^= 1453994832; 82 | x[2] ^= 1736282519; 83 | x[3] ^= -1301273892; 84 | 85 | int r; 86 | int mid; 87 | for(r = 0; r < 32; r += 4) { 88 | mid = x[1] ^ x[2] ^ x[3] ^ this.CK[r + 0]; 89 | mid = this.ByteSub(mid); 90 | rk[r + 0] = x[0] ^= this.L2(mid); 91 | mid = x[2] ^ x[3] ^ x[0] ^ this.CK[r + 1]; 92 | mid = this.ByteSub(mid); 93 | rk[r + 1] = x[1] ^= this.L2(mid); 94 | mid = x[3] ^ x[0] ^ x[1] ^ this.CK[r + 2]; 95 | mid = this.ByteSub(mid); 96 | rk[r + 2] = x[2] ^= this.L2(mid); 97 | mid = x[0] ^ x[1] ^ x[2] ^ this.CK[r + 3]; 98 | mid = this.ByteSub(mid); 99 | rk[r + 3] = x[3] ^= this.L2(mid); 100 | } 101 | 102 | if (CryptFlag == 0) { 103 | for(r = 0; r < 16; ++r) { 104 | mid = rk[r]; 105 | rk[r] = rk[31 - r]; 106 | rk[31 - r] = mid; 107 | } 108 | } 109 | 110 | } 111 | 112 | public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) { 113 | int point = 0; 114 | int[] round_key = new int[32]; 115 | this.SMS4KeyExt(key, round_key, CryptFlag); 116 | byte[] input = new byte[16]; 117 | 118 | for(byte[] output = new byte[16]; inLen >= 16; point += 16) { 119 | input = Arrays.copyOfRange(in, point, point + 16); 120 | this.SMS4Crypt(input, output, round_key); 121 | System.arraycopy(output, 0, out, point, 16); 122 | inLen -= 16; 123 | } 124 | 125 | return 0; 126 | } 127 | 128 | public static String encodeSMS4(String plaintext, byte[] key) { 129 | if (plaintext != null && !plaintext.equals("")) { 130 | for(int i = plaintext.getBytes().length % 16; i < 16; ++i) { 131 | plaintext = plaintext + '\u0000'; 132 | } 133 | 134 | return byte2hex(encodeSMS4(plaintext.getBytes(), key)); 135 | } else { 136 | return null; 137 | } 138 | } 139 | 140 | public static byte[] encodeSMS4(byte[] plaintext, byte[] key) { 141 | byte[] ciphertext = new byte[plaintext.length]; 142 | int k = 0; 143 | 144 | for(int plainLen = plaintext.length; k + 16 <= plainLen; k += 16) { 145 | byte[] cellPlain = new byte[16]; 146 | 147 | for(int i = 0; i < 16; ++i) { 148 | cellPlain[i] = plaintext[k + i]; 149 | } 150 | 151 | byte[] cellCipher = encode16(cellPlain, key); 152 | 153 | for(int i = 0; i < cellCipher.length; ++i) { 154 | ciphertext[k + i] = cellCipher[i]; 155 | } 156 | } 157 | 158 | return ciphertext; 159 | } 160 | 161 | public static String decodeSMS4(String ciphertext, byte[] key) { 162 | if (StringUtils.isEmpty(ciphertext)) { 163 | return null; 164 | } else { 165 | try { 166 | byte[] plaintext = hex2byte(ciphertext.getBytes()); 167 | byte[] cipher = new byte[plaintext.length]; 168 | cipher = decodeSMS4(plaintext, key); 169 | int length = cipher.length; 170 | 171 | for(int i = 0; i < length; ++i) { 172 | if (cipher[i] == 0) { 173 | length = i; 174 | break; 175 | } 176 | } 177 | 178 | return new String(cipher, 0, length); 179 | } catch (Exception var6) { 180 | throw new CommonException("解密失败!"); 181 | } 182 | } 183 | } 184 | 185 | public static byte[] decodeSMS4(byte[] ciphertext, byte[] key) { 186 | byte[] plaintext = new byte[ciphertext.length]; 187 | int k = 0; 188 | 189 | for(int cipherLen = ciphertext.length; k + 16 <= cipherLen; k += 16) { 190 | byte[] cellCipher = new byte[16]; 191 | 192 | for(int i = 0; i < 16; ++i) { 193 | cellCipher[i] = ciphertext[k + i]; 194 | } 195 | 196 | byte[] cellPlain = decode16(cellCipher, key); 197 | 198 | for(int i = 0; i < cellPlain.length; ++i) { 199 | plaintext[k + i] = cellPlain[i]; 200 | } 201 | } 202 | 203 | return plaintext; 204 | } 205 | 206 | private static String byte2hex(byte[] b) { 207 | StringBuilder hs = new StringBuilder(); 208 | 209 | for(int n = 0; b != null && n < b.length; ++n) { 210 | String stmp = Integer.toHexString(b[n] & 255); 211 | if (stmp.length() == 1) { 212 | hs.append('0'); 213 | } 214 | 215 | hs.append(stmp); 216 | } 217 | 218 | return hs.toString().toUpperCase(); 219 | } 220 | 221 | private static byte[] hex2byte(byte[] b) { 222 | if (b.length % 2 != 0) { 223 | throw new IllegalArgumentException(); 224 | } else { 225 | byte[] b2 = new byte[b.length / 2]; 226 | 227 | for(int n = 0; n < b.length; n += 2) { 228 | String item = new String(b, n, 2); 229 | b2[n / 2] = (byte)Integer.parseInt(item, 16); 230 | } 231 | 232 | return b2; 233 | } 234 | } 235 | 236 | private static byte[] encode16(byte[] plaintext, byte[] key) { 237 | byte[] cipher = new byte[16]; 238 | SMS4 sm4 = new SMS4(); 239 | sm4.sms4(plaintext, 16, key, cipher, 1); 240 | return cipher; 241 | } 242 | 243 | private static byte[] decode16(byte[] ciphertext, byte[] key) { 244 | byte[] plain = new byte[16]; 245 | SMS4 sm4 = new SMS4(); 246 | sm4.sms4(ciphertext, 16, key, plain, 0); 247 | return plain; 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /SMS4_Decrypt/src/main/java/com/exception/CommonException.java: -------------------------------------------------------------------------------- 1 | package com.exception; 2 | 3 | public class CommonException extends RuntimeException { 4 | public int errorCode = -1; 5 | 6 | public CommonException(String message) { 7 | super(message); 8 | } 9 | 10 | public CommonException(String message, Throwable e) { 11 | super(message, e); 12 | } 13 | 14 | public CommonException(int errorCode, String message) { 15 | super(message); 16 | this.errorCode = errorCode; 17 | } 18 | 19 | public CommonException(int errorCode, String message, Throwable e) { 20 | super(message, e); 21 | this.errorCode = errorCode; 22 | } 23 | 24 | public int getErrorCode() { 25 | return this.errorCode; 26 | } 27 | 28 | public void setErrorCode(int errorCode) { 29 | this.errorCode = errorCode; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SMS4_Decrypt/target/SMS4_Decrypt-1.0-SNAPSHOT-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SMS4_Decrypt/5bcc94ba9b24f343864af763fbaa32161012ba34/SMS4_Decrypt/target/SMS4_Decrypt-1.0-SNAPSHOT-jar-with-dependencies.jar -------------------------------------------------------------------------------- /SMS4_Decrypt/target/SMS4_Decrypt-1.0-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SMS4_Decrypt/5bcc94ba9b24f343864af763fbaa32161012ba34/SMS4_Decrypt/target/SMS4_Decrypt-1.0-SNAPSHOT.jar -------------------------------------------------------------------------------- /SMS4_Decrypt/target/classes/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SMS4_Decrypt/5bcc94ba9b24f343864af763fbaa32161012ba34/SMS4_Decrypt/target/classes/Main.class -------------------------------------------------------------------------------- /SMS4_Decrypt/target/classes/com/common/utils/SMS4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SMS4_Decrypt/5bcc94ba9b24f343864af763fbaa32161012ba34/SMS4_Decrypt/target/classes/com/common/utils/SMS4.class -------------------------------------------------------------------------------- /SMS4_Decrypt/target/classes/com/exception/CommonException.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SMS4_Decrypt/5bcc94ba9b24f343864af763fbaa32161012ba34/SMS4_Decrypt/target/classes/com/exception/CommonException.class --------------------------------------------------------------------------------