· 9 years ago · Dec 05, 2016, 03:54 PM
1import java.math.BigInteger;
2import java.util.*;
3import javax.crypto.Cipher;
4import javax.crypto.SecretKey;
5import javax.crypto.spec.SecretKeySpec;
6
7/**
8 *
9 * @author MAXIMUM13
10 */
11public class DESModel {
12
13 private static final Cipher CIPHER;
14 private static final int RADIX = 16;
15 private static final int N = 8;
16 private static final int IND0 = -128;
17 private static final int IND1 = 128;
18
19 static {
20 Cipher cipher = null;
21 try {
22 cipher = Cipher.getInstance("DES/ECB/NoPadding");
23 } catch (Exception exc) {
24 }
25 CIPHER = cipher;
26 }
27
28 public static void main(String[] args) throws Exception {
29 compute();
30 }
31
32 private static void compute() throws Exception {
33 String lastKey0Bytes = "37e1748602";
34 String lastKey1Bytes = "d9d4b016c2";
35
36 String openText0 = "European";
37 String cipherText0 = "99f7b96a3c8ad748";
38
39 String openText1 = "exercise";
40 String cipherText1 = "f8e84cb72ea2ef58";
41
42 String cipherText2 = "e1d785c6dcfb726c";
43
44 byte[] key0LastBytes = toBytes(lastKey0Bytes, RADIX);
45 byte[] key1LastBytes = toBytes(lastKey1Bytes, RADIX);
46
47 byte[] openText0Bytes = openText0.getBytes();
48 byte[] openText1Bytes = openText1.getBytes();
49
50 byte[] cipherText0Bytes = toBytes(cipherText0, RADIX);
51 byte[] cipherText1Bytes = toBytes(cipherText1, RADIX);
52 byte[] cipherText2Bytes = toBytes(cipherText2, RADIX);
53
54 byte[] key0Bytes = new byte[N];
55 int len = key0LastBytes.length;
56 System.arraycopy(key0LastBytes, 0, key0Bytes, N - len, len);
57
58 byte[] key1Bytes = new byte[N];
59 len = key1LastBytes.length;
60 System.arraycopy(key1LastBytes, 0, key1Bytes, N - len, len);
61
62 final Map<String, SecretKey> keysMap = new TreeMap<>();
63
64 for (int i = IND0; i < IND1; i++, i++) {
65 key1Bytes[0] = (byte) i;
66 System.out.println(i);
67 for (int j = IND0; j < IND1; j++, j++) {
68 key1Bytes[1] = (byte) j;
69 for (int k = IND0; k < IND1; k++, k++) {
70 key1Bytes[2] = (byte) k;
71 SecretKey secretKey = new SecretKeySpec(key1Bytes.clone(), "DES");
72
73 byte[] cText0 = doFinal(Cipher.ENCRYPT_MODE, openText0Bytes, secretKey);
74 String cText = new String(cText0);
75 keysMap.put(cText, secretKey);
76 }
77 }
78 }
79
80 System.out.println();
81
82 int c = 0;
83 loop:
84 {
85 for (int i = IND0; i < IND1; i++, i++) {
86 key0Bytes[0] = (byte) i;
87 System.out.println(i);
88 for (int j = IND0; j < IND1; j++, j++) {
89 key0Bytes[1] = (byte) j;
90 for (int k = IND0; k < IND1; k++, k++) {
91 key0Bytes[2] = (byte) k;
92 SecretKey secretKey = new SecretKeySpec(key0Bytes.clone(), "DES");
93
94 byte[] cText0 = doFinal(Cipher.DECRYPT_MODE, cipherText0Bytes, secretKey);
95 String cText = new String(cText0);
96 if (keysMap.containsKey(cText)) {
97 c++;
98 SecretKey key0 = secretKey;
99 SecretKey key1 = keysMap.get(cText);
100 boolean f = check(openText1Bytes, cipherText1Bytes, key0, key1);
101 if (f) {
102 byte[] openTextBytes = doFinal(Cipher.DECRYPT_MODE, cipherText2Bytes, key1, key0);
103 String openText = new String(openTextBytes);
104
105 System.out.println();
106 System.out.println("map.size(): " + keysMap.size());
107 System.out.println("keys: " + c);
108 System.out.println("open text: " + openText);
109 System.out.println("key0: " + Utils.toHexString(key0.getEncoded()));
110 System.out.println("key1: " + Utils.toHexString(key1.getEncoded()));
111 break loop;
112 }
113 }
114 }
115 }
116 }
117 }
118 }
119
120 private static boolean check(byte[] openText, byte[] cipherText,
121 SecretKey key0, SecretKey key1) throws Exception {
122 return Arrays.equals(doFinal(Cipher.ENCRYPT_MODE, openText, key0, key1), cipherText);
123 }
124
125 private static byte[] doFinal(int mode, byte[] message,
126 SecretKey key0, SecretKey key1) throws Exception {
127 return doFinal(mode, doFinal(mode, message, key1), key0);
128 }
129
130 private static byte[] doFinal(int mode, byte[] message,
131 SecretKey key) throws Exception {
132 CIPHER.init(mode, key);
133 return CIPHER.doFinal(message);
134 }
135
136 public static byte[] toBytes(String s, int radix) {
137 byte[] a0 = new BigInteger(s, radix).toByteArray();
138 int ind = a0.length > 0 && a0[0] == 0 ? 1 : 0;
139 byte[] a1 = new byte[a0.length - ind];
140 System.arraycopy(a0, ind, a1, 0, a1.length);
141 return a1;
142 }
143}