|
1 | 1 | #!/usr/bin/env python3
|
2 | 2 |
|
3 | 3 | import sys
|
4 |
| -import dicks |
| 4 | +import getopt |
| 5 | +import numpy as np |
| 6 | +import math |
| 7 | + |
| 8 | +PC1TAB = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] |
| 9 | +PC2TAB = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] |
| 10 | +IPTAB = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] |
| 11 | +ETAB = [ 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12,11, 12, 13, 14, 15, 16,15, 16, 17, 18, 19, 20,19, 20, 21, 22, 23, 24,23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0] |
| 12 | + |
| 13 | +SBOX = [ |
| 14 | + 0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07, |
| 15 | + 0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38, |
| 16 | + 0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50, |
| 17 | + 0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D, |
| 18 | + 0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A, |
| 19 | + 0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5, |
| 20 | + 0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F, |
| 21 | + 0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9, |
| 22 | + 0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28, |
| 23 | + 0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1, |
| 24 | + 0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7, |
| 25 | + 0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C, |
| 26 | + 0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F, |
| 27 | + 0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9, |
| 28 | + 0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84, |
| 29 | + 0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E, |
| 30 | + 0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9, |
| 31 | + 0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86, |
| 32 | + 0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E, |
| 33 | + 0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53, |
| 34 | + 0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B, |
| 35 | + 0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38, |
| 36 | + 0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6, |
| 37 | + 0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D, |
| 38 | + 0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61, |
| 39 | + 0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86, |
| 40 | + 0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92, |
| 41 | + 0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C, |
| 42 | + 0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7, |
| 43 | + 0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92, |
| 44 | + 0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58, |
| 45 | + 0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B |
| 46 | +] |
| 47 | + |
| 48 | +CONFIG_KEY = None |
| 49 | +CONFIG_KNOWNPT = None |
| 50 | +CONFIG_KNOWNCT = None |
| 51 | + |
| 52 | +def usage(): |
| 53 | + print("./des_key_recombiner.py -k [hexkey] -p [plaintext] -c [ciphertext]") |
| 54 | + |
| 55 | +if len(sys.argv) == 1: |
| 56 | + usage() |
| 57 | + sys.exit(0) |
| 58 | + |
| 59 | +args, rem = getopt.getopt(sys.argv[1:],"k:p:c:",["--key=","--plaintext=","--ciphertext="]) |
| 60 | +for arg,val in args: |
| 61 | + if arg in ["-k","--key"]: |
| 62 | + CONFIG_KEY = binascii.unhexlify(val) |
| 63 | + elif arg in ["-p","--plaintext"]: |
| 64 | + CONFIG_KNOWNPT = binascii.unhexlify(val) |
| 65 | + elif arg in ["-c","--ciphertext"]: |
| 66 | + CONFIG_KNOWNCT = binascii.unhexlify(val) |
| 67 | + |
| 68 | +if (CONFIG_KEY is None) or (CONFIG_KNOWNPT is None) or (CONFIG_KNOWNCT is None): |
| 69 | + print("You must supply -k (hexkey), -p (hexplain) and -c (hexcipher)") |
| 70 | + sys.exit(0) |
| 71 | + |
| 72 | +class desRecombine: |
| 73 | + def __init__(self,pt): |
| 74 | + pt_temp = [] |
| 75 | + for pt_byte in pt: |
| 76 | + pt_temp += [ord(x) - ord('0') for x in bin(pt_byte)[2:].rjust(6,"0")] |
| 77 | + # pt_temp += [0,0] |
| 78 | + # pt_temp += [px[0], px[2], px[3], px[4], px[5], px[1]] |
| 79 | + pt_temp_recovered = [int(mapToInteger(pt_temp[i:i + 8],8)) for i in range(0, len(pt_temp), 8)] |
| 80 | + # print [hex(i) for i in pt_temp_recovered] |
| 81 | + inv_pt = inv_permute(PC2TAB,pt_temp) # 48 bits in, 56 bits out |
| 82 | + # print inv_pt |
| 83 | + # print len(inv_pt) |
| 84 | + inv_pt_hexlify = [int(mapToInteger(inv_pt[i:i + 8],8)) for i in range(0, len(inv_pt), 8)] |
| 85 | + # print "INVERTED PC2" |
| 86 | + # print [hex(h) for h in inv_pt_hexlify] |
| 87 | + REAL_INVPC2 = [0xc0, 0x85, 0x66, 0x9d, 0x75, 0xc6, 0x7d] |
| 88 | + x = bytesToBitstring(REAL_INVPC2) |
| 89 | + for i in range(0,len(inv_pt)): |
| 90 | + if inv_pt[i] != x[i]: |
| 91 | + pass |
| 92 | + # print "mismatch!", |
| 93 | + # print inv_pt[i] |
| 94 | + # at this point, inv_pt is our "source material" |
| 95 | + inv_pt_L = inv_pt[:28] |
| 96 | + inv_pt_L = [inv_pt_L[27]] + inv_pt_L[:27] |
| 97 | + inv_pt_R = inv_pt[28:] |
| 98 | + inv_pt_R = [inv_pt_R[27]] + inv_pt_R[:27] |
| 99 | + inv_pt = inv_pt_L + inv_pt_R |
| 100 | + # print inv_pt |
| 101 | + # the last bit is always lost... |
| 102 | + inv_pc1 = inv_permute(PC1TAB,inv_pt,3) + [3] |
| 103 | + print(inv_pc1) |
| 104 | + # REAL_KEY = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6] |
| 105 | + # real_exp = bytesToBitstring(REAL_KEY) |
| 106 | + # for i in range(0,len(real_exp)): |
| 107 | + # if inv_pc1[i] != real_exp[i]: |
| 108 | + # print "mismatch! %d" % inv_pc1[i] |
| 109 | + self.inv_pc1 = inv_pc1 |
| 110 | + |
| 111 | + # input in bytestring format |
| 112 | + def bruteKey(self,knownPlain,knownCipher): |
| 113 | + for i in range(0,256): |
| 114 | + # print "TRYING %d" % i |
| 115 | + test_template = [ord(x) - ord('0') for x in bin(i)[2:].rjust(8,"0")] |
| 116 | + # print test_template |
| 117 | + try_key = [0] * len(self.inv_pc1) |
| 118 | + for tposn in range(0,len(self.inv_pc1)): |
| 119 | + if self.inv_pc1[tposn] == 2: |
| 120 | + try_key[tposn] = test_template.pop() |
| 121 | + elif try_key[tposn] == 3: |
| 122 | + self.inv_pc1[tposn] = 0 |
| 123 | + else: |
| 124 | + try_key[tposn] = self.inv_pc1[tposn] |
| 125 | + # print try_key |
| 126 | + try_hexlified = bitstringToBytes(try_key) |
| 127 | + try_hexstr = "".join([chr(xt) for xt in try_hexlified]) |
| 128 | + # print binascii.hexlify(try_hexstr) |
| 129 | + d = DES.new(try_hexstr,DES.MODE_ECB) |
| 130 | + if d.encrypt(stringify(knownPlain)) == stringify(knownCipher): |
| 131 | + print("GOTCHA: %s" % binascii.hexlify(try_hexstr)) |
| 132 | + # else: |
| 133 | + # print binascii.hexlify(d.encrypt(stringify(knownPlain))) |
| 134 | + |
| 135 | +desRecombine |
0 commit comments