大智慧协议的Java破解

发现大智慧所有版本的登录协议都是一样的。以用户名 111111 密码 222222 登录为例,


1. 第一阶段的数据为:

00000000  36 10 34 00 00 00 03 00  3E 7A 2A 14 64 5C 36 C0   6.4..... >z*.d/6.
00000010  AE A2 08 6D 2E 43 9D 97  BB E0 E5 40 DC CC 3B FC    ...m.C.. ...@..;.
00000020  3C 63 0A 8D 5E C9 AB 03  8F D9 A2 98 32 52 4D 2A   <c..^... ....2RM*
00000030  DE BF 01 F8 06 CB A6 14  32 32 32 32                        ........ 2222

 36 10 34 00 00 00 03 00  为这个请求的头,
3610 = 1036 为请求的标识
34 00 00 00 为这个请求的长度(长整型 00 00 00 34 )
03 00  未知作用

 

服务器返回

00000000  31 10 39 00 00 00 03 00  50 5E 7C C0 A2 2E 6C 32   1.9..... P^|...l2
00000010  4E 50 DB DD 6B F4 EF 87  02 36 11 8E 7A 4E 02 26   NP..k... .6..zN.&
00000020  BF 15 E8 8F C9 FC DB 42  5F B5 2F 66 AD 2D 55 32   .......B _./f.-U2
00000030  69 5D EB AC A3 11 42 79  7C 0D 0A 3C 2F 41 3E 0D   i]....By |..</A>.
00000040  0A   

 31 10 39 00 00 00 03 00  跟请求的格式一致。31 10  说明后面还有数据,不是最后一个数据。

 

第二阶段的数据格式为

00000000  36 10 04 00 00 00 03 00  01 00 00 00                       6....... ....

该请求可有可无

 

服务器返回认证的结果。

00000000  32 10 63 01 00 00 13 00  3B 39 B4 ED 93 37 FA 19   2.c..... ;9...7..
00000010  EB F8 AF 3C 28 78 49 62  E7 0B 8B F7 8E 57 97 CC   ...<(xIb .....W..
00000020  2C 8F 04 44 70 59 6C BB  E1 95 1F AD 85 9F 49 81   ,..DpYl. ......I.
00000030  CF 30 0A 80 55 9A 68 68  3A E3 BD 51 13 9E FA 4C   .0..U.hh :..Q...L
00000040  C1 A6 9F 3E 02 F2 7D 23  B1 08 09 7A C8 A9 60 02   ...>..}# ...z..`.
00000050  7D 10 3A 38 E8 C3 36 4E  64 DB CF 28 32 83 99 3E   }.:8..6N d..(2..>
00000060  B4 22 85 30 1F AF 32 15  BC 18 3B 38 86 D1 F0 F3   .".0..2. ..;8....
00000070  3C 98 19 D7 FE FB 01 7D  A0 70 A3 90 A9 0A EF 69   <......} .p.....i
00000080  7C A6 44 61 BE 18 39 B4  E6 6D 2D C3 C2 0C F8 F5   |.Da..9. .m-.....
00000090  BB DB B3 FF 56 36 C9 9C  94 D0 46 CD 00 26 A4 05   ....V6.. ..F..&..
000000A0  FD 35 5B 61 05 08 11 FD  0A FE 7E 95 1B 27 50 45   .5[a.... ..~..'PE
000000B0  EE AB 61 5D E5 0B F1 6F  00 BE EA BA F8 90 F6 46   ..a]...o .......F
000000C0  E2 60 F8 EC CB E4 52 3A  78 4F 5C 31 50 E8 A2 63   .`....R: xO/1P..c
000000D0  9C AF 27 74 65 1A FC 96  0A B5 8B 3A 28 33 22 11   ..'te... ...:(3".
000000E0  4D 6F 40 70 D1 21 47 5D  5A 46 A6 4A F6 69 D0 0A   Mo@p.!G] ZF.J.i..
000000F0  4B 46 C0 7C 6F FE D9 B9  D1 B1 9E 61 F1 25 65 59   KF.|o... ...a.%eY
00000100  1B E1 C5 66 2A DE 8F 7E  CE 51 A3 A4 05 61 46 7D   ...f*..~ .Q...aF}
00000110  E1 6E DE CA 9B DB 89 A4  D1 C2 B2 F0 51 DC 45 A4   .n...... ....Q.E.
00000120  26 CB B2 F4 9A 7A EF 41  EE 6F 2A D6 DC B9 84 41   &....z.A .o*....A
00000130  59 65 7B 6A FD 31 96 51  66 5A 1B 88 5B 9A 93 30   Ye{j.1.Q fZ..[..0
00000140  04 7E 49 9F 50 0C EB 3F  2C D0 8C 73 32 FA D4 B7   .~I.P..? ,..s2...
00000150  0D 9F B9 C0 AF 70 3B 10  4C 0C E1 FD DB 1C B3 F0   .....p;. L.......
00000160  24 13 2E F2 4D 2D 56 7D  34 D7 E1                             $...M-V} 4..

 

 

接下来就是具体的协议内容了。

 

大智慧采用的是AES加密算法,具体算法Google一下。

 

大智慧采用的AES key 是 "7654321 Now is t"

 

以第一个服务器返回的数据为例:

00000000  31 10 39 00 00 00 03 00  50 5E 7C C0 A2 2E 6C 32   1.9..... P^|...l2
00000010  4E 50 DB DD 6B F4 EF 87  02 36 11 8E 7A 4E 02 26   NP..k... .6..zN.&
00000020  BF 15 E8 8F C9 FC DB 42  5F B5 2F 66 AD 2D 55 32   .......B _./f.-U2
00000030  69 5D EB AC A3 11 42 79  7C 0D 0A 3C 2F 41 3E 0D   i]....By |..</A>.
00000040  0A   

 

解密后的明文为:

SFLogInPack=ABK
<A>
m_intLoginRet|
4294967286|
</A>

 

AES 加密算法的Java 实现

 

package cn.jteam.dzh; public class Rijndael { public Rijndael() { } /** * Flag to setup the encryption key schedule. */ public static final int DIR_ENCRYPT = 1; /** * Flag to setup the decryption key schedule. */ public static final int DIR_DECRYPT = 2; /** * Flag to setup both key schedules (encryption/decryption). */ public static final int DIR_BOTH = (DIR_ENCRYPT | DIR_DECRYPT); /** * AES block size in bits (N.B. the Rijndael algorithm itself allows for * other sizes). */ public static final int BLOCK_BITS = 128; /** * AES block size in bytes (N.B. the Rijndael algorithm itself allows for * other sizes). */ public static final int BLOCK_SIZE = (BLOCK_BITS >>> 3); /** * Substitution table (S-box). */ private static final String SS = "/u637C/u777B/uF26B/u6FC5/u3001/u672B/uFED7/uAB76" + "/uCA82/uC97D/uFA59/u47F0/uADD4/uA2AF/u9CA4/u72C0" + "/uB7FD/u9326/u363F/uF7CC/u34A5/uE5F1/u71D8/u3115" + "/u04C7/u23C3/u1896/u059A/u0712/u80E2/uEB27/uB275" + "/u0983/u2C1A/u1B6E/u5AA0/u523B/uD6B3/u29E3/u2F84" + "/u53D1/u00ED/u20FC/uB15B/u6ACB/uBE39/u4A4C/u58CF" + "/uD0EF/uAAFB/u434D/u3385/u45F9/u027F/u503C/u9FA8" + "/u51A3/u408F/u929D/u38F5/uBCB6/uDA21/u10FF/uF3D2" + "/uCD0C/u13EC/u5F97/u4417/uC4A7/u7E3D/u645D/u1973" + "/u6081/u4FDC/u222A/u9088/u46EE/uB814/uDE5E/u0BDB" + "/uE032/u3A0A/u4906/u245C/uC2D3/uAC62/u9195/uE479" + "/uE7C8/u376D/u8DD5/u4EA9/u6C56/uF4EA/u657A/uAE08" + "/uBA78/u252E/u1CA6/uB4C6/uE8DD/u741F/u4BBD/u8B8A" + "/u703E/uB566/u4803/uF60E/u6135/u57B9/u86C1/u1D9E" + "/uE1F8/u9811/u69D9/u8E94/u9B1E/u87E9/uCE55/u28DF" + "/u8CA1/u890D/uBFE6/u4268/u4199/u2D0F/uB054/uBB16"; private static final byte[] Se = new byte[256]; private static final int[] Te0 = new int[256], Te1 = new int[256], Te2 = new int[256], Te3 = new int[256]; private static final byte[] Sd = new byte[256]; private static final int[] Td0 = new int[256], Td1 = new int[256], Td2 = new int[256], Td3 = new int[256]; /** * Round constants */ private static final int[] rcon = new int[10]; /* * for 128-bit blocks, * Rijndael never uses more * than 10 rcon values */ /** * Number of rounds (depends on key size). */ private int Nr = 0; private int Nk = 0; private int Nw = 0; /** * Encryption key schedule */ private int rek[] = null; /** * Decryption key schedule */ private int rdk[] = null; static { /* * Te0[x] = Se[x].[02, 01, 01, 03]; Te1[x] = Se[x].[03, 02, 01, 01]; * Te2[x] = Se[x].[01, 03, 02, 01]; Te3[x] = Se[x].[01, 01, 03, 02]; * * Td0[x] = Sd[x].[0e, 09, 0d, 0b]; Td1[x] = Sd[x].[0b, 0e, 09, 0d]; * Td2[x] = Sd[x].[0d, 0b, 0e, 09]; Td3[x] = Sd[x].[09, 0d, 0b, 0e]; */ int ROOT = 0x11B; int s1, s2, s3, i1, i2, i4, i8, i9, ib, id, ie, t; for (i1 = 0; i1 < 256; i1++) { char c = SS.charAt(i1 >>> 1); s1 = (byte) ((i1 & 1) == 0 ? c >>> 8 : c) & 0xff; s2 = s1 << 1; if (s2 >= 0x100) { s2 ^= ROOT; } s3 = s2 ^ s1; i2 = i1 << 1; if (i2 >= 0x100) { i2 ^= ROOT; } i4 = i2 << 1; if (i4 >= 0x100) { i4 ^= ROOT; } i8 = i4 << 1; if (i8 >= 0x100) { i8 ^= ROOT; } i9 = i8 ^ i1; ib = i9 ^ i2; id = i9 ^ i4; ie = i8 ^ i4 ^ i2; Se[i1] = (byte) s1; Te0[i1] = t = (s2 << 24) | (s1 << 16) | (s1 << 8) | s3; Te1[i1] = (t >>> 8) | (t << 24); Te2[i1] = (t >>> 16) | (t << 16); Te3[i1] = (t >>> 24) | (t << 8); Sd[s1] = (byte) i1; Td0[s1] = t = (ie << 24) | (i9 << 16) | (id << 8) | ib; Td1[s1] = (t >>> 8) | (t << 24); Td2[s1] = (t >>> 16) | (t << 16); Td3[s1] = (t >>> 24) | (t << 8); } /* * round constants */ int r = 1; rcon[0] = r << 24; for (int i = 1; i < 10; i++) { r <<= 1; if (r >= 0x100) { r ^= ROOT; } rcon[i] = r << 24; } } /** * Expand a cipher key into a full encryption key schedule. * * @param cipherKey * the cipher key (128, 192, or 256 bits). */ private void expandKey(byte[] cipherKey) { int temp, r = 0; for (int i = 0, k = 0; i < Nk; i++, k += 4) { rek[i] = ((cipherKey[k]) << 24) | ((cipherKey[k + 1] & 0xff) << 16) | ((cipherKey[k + 2] & 0xff) << 8) | ((cipherKey[k + 3] & 0xff)); } for (int i = Nk, n = 0; i < Nw; i++, n--) { temp = rek[i - 1]; if (n == 0) { n = Nk; temp = ((Se[(temp >>> 16) & 0xff]) << 24) | ((Se[(temp >>> 8) & 0xff] & 0xff) << 16) | ((Se[(temp) & 0xff] & 0xff) << 8) | ((Se[(temp >>> 24)] & 0xff)); temp ^= rcon[r++]; } else if (Nk == 8 && n == 4) { temp = ((Se[(temp >>> 24)]) << 24) | ((Se[(temp >>> 16) & 0xff] & 0xff) << 16) | ((Se[(temp >>> 8) & 0xff] & 0xff) << 8) | ((Se[(temp) & 0xff] & 0xff)); } rek[i] = rek[i - Nk] ^ temp; } temp = 0; } /** * Compute the decryption schedule from the encryption schedule . */ private void invertKey() { int d = 0, e = 4 * Nr, w; /* * apply the inverse MixColumn transform to all round keys but the first * and the last: */ rdk[d] = rek[e]; rdk[d + 1] = rek[e + 1]; rdk[d + 2] = rek[e + 2]; rdk[d + 3] = rek[e + 3]; d += 4; e -= 4; for (int r = 1; r < Nr; r++) { w = rek[e]; rdk[d] = Td0[Se[(w >>> 24)] & 0xff] ^ Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w) & 0xff] & 0xff]; w = rek[e + 1]; rdk[d + 1] = Td0[Se[(w >>> 24)] & 0xff] ^ Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w) & 0xff] & 0xff]; w = rek[e + 2]; rdk[d + 2] = Td0[Se[(w >>> 24)] & 0xff] ^ Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w) & 0xff] & 0xff]; w = rek[e + 3]; rdk[d + 3] = Td0[Se[(w >>> 24)] & 0xff] ^ Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w) & 0xff] & 0xff]; d += 4; e -= 4; } rdk[d] = rek[e]; rdk[d + 1] = rek[e + 1]; rdk[d + 2] = rek[e + 2]; rdk[d + 3] = rek[e + 3]; } /** * Setup the AES key schedule for encryption, decryption, or both. * * @param cipherKey * the cipher key (128, 192, or 256 bits). * @param keyBits * size of the cipher key in bits. * @param direction * cipher direction (DIR_ENCRYPT, DIR_DECRYPT, or DIR_BOTH). */ public void makeKey(byte[] cipherKey, int keyBits, int direction) throws RuntimeException { // check key size: if (keyBits != 128 && keyBits != 192 && keyBits != 256) { throw new RuntimeException("Invalid AES key size (" + keyBits + " bits)"); } Nk = keyBits >>> 5; Nr = Nk + 6; Nw = 4 * (Nr + 1); rek = new int[Nw]; rdk = new int[Nw]; if ((direction & DIR_BOTH) != 0) { expandKey(cipherKey); /* * for (int r = 0; r <= Nr; r++) { System.out.print("RK" + r + "="); * for (int i = 0; i < 4; i++) { int w = rek[4*r + i]; * System.out.print(" " + Integer.toHexString(w)); } * System.out.println(); } */ if ((direction & DIR_DECRYPT) != 0) { invertKey(); } } /* System.out.println(); System.out.print("Td0=="); for (int i = 0; i < Td0.length; i++) { System.out.print(" " + Integer.toHexString(Td0[i])); } System.out.println(); System.out.print("Td1=="); for (int i = 0; i < Td1.length; i++) { System.out.print(" " + Integer.toHexString(Td1[i])); } System.out.println(); System.out.print("Td2=="); for (int i = 0; i < Td2.length; i++) { System.out.print(" " + Integer.toHexString(Td2[i])); } System.out.println(); System.out.print("Td3=="); for (int i = 0; i < Td1.length; i++) { System.out.print(" " + Integer.toHexString(Td3[i])); } System.out.println(); System.out.print("Te0=="); for (int i = 0; i < Te0.length; i++) { System.out.print(" " + Integer.toHexString(Te0[i])); } System.out.println(); System.out.print("Te1=="); for (int i = 0; i < Te1.length; i++) { System.out.print(" " + Integer.toHexString(Te1[i])); } System.out.println(); System.out.print("Te2=="); for (int i = 0; i < Te2.length; i++) { System.out.print(" " + Integer.toHexString(Te2[i])); } System.out.println(); System.out.print("Te3=="); for (int i = 0; i < Te3.length; i++) { System.out.print(" " + Integer.toHexString(Te3[i])); } System.out.println(); */ } /** * Setup the AES key schedule (any cipher direction). * * @param cipherKey * the cipher key (128, 192, or 256 bits). * @param keyBits * size of the cipher key in bits. */ public void makeKey(byte[] cipherKey, int keyBits) throws RuntimeException { makeKey(cipherKey, keyBits, DIR_BOTH); } /** * Encrypt exactly one block (BLOCK_SIZE bytes) of plaintext. * * @param pt * plaintext block. * @param ct * ciphertext block. */ public void encrypt(byte[] pt, byte[] ct) { /* * map byte array block to cipher state and add initial round key: */ int k = 0, v; int t0 = ((pt[0]) << 24 | (pt[1] & 0xff) << 16 | (pt[2] & 0xff) << 8 | (pt[3] & 0xff)) ^ rek[0]; int t1 = ((pt[4]) << 24 | (pt[5] & 0xff) << 16 | (pt[6] & 0xff) << 8 | (pt[7] & 0xff)) ^ rek[1]; int t2 = ((pt[8]) << 24 | (pt[9] & 0xff) << 16 | (pt[10] & 0xff) << 8 | (pt[11] & 0xff)) ^ rek[2]; int t3 = ((pt[12]) << 24 | (pt[13] & 0xff) << 16 | (pt[14] & 0xff) << 8 | (pt[15] & 0xff)) ^ rek[3]; /* * Nr - 1 full rounds: */ for (int r = 1; r < Nr; r++) { k += 4; int a0 = Te0[(t0 >>> 24)] ^ Te1[(t1 >>> 16) & 0xff] ^ Te2[(t2 >>> 8) & 0xff] ^ Te3[(t3) & 0xff] ^ rek[k]; int a1 = Te0[(t1 >>> 24)] ^ Te1[(t2 >>> 16) & 0xff] ^ Te2[(t3 >>> 8) & 0xff] ^ Te3[(t0) & 0xff] ^ rek[k + 1]; int a2 = Te0[(t2 >>> 24)] ^ Te1[(t3 >>> 16) & 0xff] ^ Te2[(t0 >>> 8) & 0xff] ^ Te3[(t1) & 0xff] ^ rek[k + 2]; int a3 = Te0[(t3 >>> 24)] ^ Te1[(t0 >>> 16) & 0xff] ^ Te2[(t1 >>> 8) & 0xff] ^ Te3[(t2) & 0xff] ^ rek[k + 3]; t0 = a0; t1 = a1; t2 = a2; t3 = a3; } /* * last round lacks MixColumn: */ k += 4; v = rek[k]; ct[0] = (byte) (Se[(t0 >>> 24)] ^ (v >>> 24)); ct[1] = (byte) (Se[(t1 >>> 16) & 0xff] ^ (v >>> 16)); ct[2] = (byte) (Se[(t2 >>> 8) & 0xff] ^ (v >>> 8)); ct[3] = (byte) (Se[(t3) & 0xff] ^ (v)); v = rek[k + 1]; ct[4] = (byte) (Se[(t1 >>> 24)] ^ (v >>> 24)); ct[5] = (byte) (Se[(t2 >>> 16) & 0xff] ^ (v >>> 16)); ct[6] = (byte) (Se[(t3 >>> 8) & 0xff] ^ (v >>> 8)); ct[7] = (byte) (Se[(t0) & 0xff] ^ (v)); v = rek[k + 2]; ct[8] = (byte) (Se[(t2 >>> 24)] ^ (v >>> 24)); ct[9] = (byte) (Se[(t3 >>> 16) & 0xff] ^ (v >>> 16)); ct[10] = (byte) (Se[(t0 >>> 8) & 0xff] ^ (v >>> 8)); ct[11] = (byte) (Se[(t1) & 0xff] ^ (v)); v = rek[k + 3]; ct[12] = (byte) (Se[(t3 >>> 24)] ^ (v >>> 24)); ct[13] = (byte) (Se[(t0 >>> 16) & 0xff] ^ (v >>> 16)); ct[14] = (byte) (Se[(t1 >>> 8) & 0xff] ^ (v >>> 8)); ct[15] = (byte) (Se[(t2) & 0xff] ^ (v)); } /** * Decrypt exactly one block (BLOCK_SIZE bytes) of ciphertext. * * @param ct * ciphertext block. * @param pt * plaintext block. */ public void decrypt(byte[] ct, byte[] pt) { /* * map byte array block to cipher state and add initial round key: */ int k = 0, v; int t0 = ((ct[0]) << 24 | (ct[1] & 0xff) << 16 | (ct[2] & 0xff) << 8 | (ct[3] & 0xff)) ^ rdk[0]; int t1 = ((ct[4]) << 24 | (ct[5] & 0xff) << 16 | (ct[6] & 0xff) << 8 | (ct[7] & 0xff)) ^ rdk[1]; int t2 = ((ct[8]) << 24 | (ct[9] & 0xff) << 16 | (ct[10] & 0xff) << 8 | (ct[11] & 0xff)) ^ rdk[2]; int t3 = ((ct[12]) << 24 | (ct[13] & 0xff) << 16 | (ct[14] & 0xff) << 8 | (ct[15] & 0xff)) ^ rdk[3]; /* * Nr - 1 full rounds: */ //System.out.println("Nr>>"+Nr); for (int r = 1; r < Nr; r++) { k += 4; int a0 = Td0[(t0 >>> 24)] ^ Td1[(t3 >>> 16) & 0xff] ^ Td2[(t2 >>> 8) & 0xff] ^ Td3[(t1) & 0xff] ^ rdk[k]; int a1 = Td0[(t1 >>> 24)] ^ Td1[(t0 >>> 16) & 0xff] ^ Td2[(t3 >>> 8) & 0xff] ^ Td3[(t2) & 0xff] ^ rdk[k + 1]; int a2 = Td0[(t2 >>> 24)] ^ Td1[(t1 >>> 16) & 0xff] ^ Td2[(t0 >>> 8) & 0xff] ^ Td3[(t3) & 0xff] ^ rdk[k + 2]; int a3 = Td0[(t3 >>> 24)] ^ Td1[(t2 >>> 16) & 0xff] ^ Td2[(t1 >>> 8) & 0xff] ^ Td3[(t0) & 0xff] ^ rdk[k + 3]; t0 = a0; t1 = a1; t2 = a2; t3 = a3; } /* * last round lacks MixColumn: */ k += 4; v = rdk[k]; pt[0] = (byte) (Sd[(t0 >>> 24)] ^ (v >>> 24)); pt[1] = (byte) (Sd[(t3 >>> 16) & 0xff] ^ (v >>> 16)); pt[2] = (byte) (Sd[(t2 >>> 8) & 0xff] ^ (v >>> 8)); pt[3] = (byte) (Sd[(t1) & 0xff] ^ (v)); v = rdk[k + 1]; pt[4] = (byte) (Sd[(t1 >>> 24)] ^ (v >>> 24)); pt[5] = (byte) (Sd[(t0 >>> 16) & 0xff] ^ (v >>> 16)); pt[6] = (byte) (Sd[(t3 >>> 8) & 0xff] ^ (v >>> 8)); pt[7] = (byte) (Sd[(t2) & 0xff] ^ (v)); v = rdk[k + 2]; pt[8] = (byte) (Sd[(t2 >>> 24)] ^ (v >>> 24)); pt[9] = (byte) (Sd[(t1 >>> 16) & 0xff] ^ (v >>> 16)); pt[10] = (byte) (Sd[(t0 >>> 8) & 0xff] ^ (v >>> 8)); pt[11] = (byte) (Sd[(t3) & 0xff] ^ (v)); v = rdk[k + 3]; pt[12] = (byte) (Sd[(t3 >>> 24)] ^ (v >>> 24)); pt[13] = (byte) (Sd[(t2 >>> 16) & 0xff] ^ (v >>> 16)); pt[14] = (byte) (Sd[(t1 >>> 8) & 0xff] ^ (v >>> 8)); pt[15] = (byte) (Sd[(t0) & 0xff] ^ (v)); } /** * Destroy all sensitive information in this object. */ protected final void finalize() { if (rek != null) { for (int i = 0; i < rek.length; i++) { rek[i] = 0; } rek = null; } if (rdk != null) { for (int i = 0; i < rdk.length; i++) { rdk[i] = 0; } rdk = null; } } public static String dumpBytes(byte[] bytes) throws Exception { StringBuffer sb = new StringBuffer(); for (byte b : bytes) { sb.append(String.format(" %02X ", b)); } return sb.toString(); } public static void main(String[] args) throws Exception { //String key="90477D78934ca7160000008067022c04"; String key = "63fac0d034d9f793199e9d6df39aa816"; //64 70 79 5B 54 7B 5F 70 2F 0C 1C 1D 28 31 6B 79 //String key = "48F4EF283CF5EF2800000000C4858000"; //String key = "504518008c451800d08c1c00207c1c00"; byte[] kb = new byte[16]; for (int i = 0; i < kb.length; i++) { String b = key.substring(i * 2, i * 2 + 2); kb[i] = (byte) Integer.parseInt(b, 16); } System.out.println(dumpBytes(kb)); String pt = "505E7CC0A22E6C324E50DBDD6BF4EF87"; byte[] pts = new byte[pt.length() / 2]; for (int i = 0; i < pts.length; i++) { String b = pt.substring(i * 2, i * 2 + 2); pts[i] = (byte) Integer.parseInt(b, 16); } System.out.println(dumpBytes(pts)); Rijndael aes = new Rijndael(); aes.makeKey(kb, 128); byte[] cts = new byte[16]; aes.decrypt(pts,cts); System.out.println(dumpBytes(cts)); } }

 

 

免责申请:以上技术仅用作学习和研究,对于其他用途引起的纠纷,本人概不负责。

 

你可能感兴趣的:(java,c,String,byte,encryption,Constants)