a b/python/key_solver_bruteforce.py
1
import itertools
2
import multiprocessing
3
import os
4
import sys
5
import time
6
from datetime import datetime, timedelta
7
8
from Crypto.Cipher import AES
9
10
filename = 'emotiv_encrypted_data_UD20160103001874_2017-04-05.17-21-32.384061.txt'
11
# filename = 'emotiv_encrypted_data_UD20160103001874_2017-04-05.17-42-23.292665.txt'
12
serial_number = 'UD20160103001874'
13
iv = os.urandom(AES.block_size)
14
15
# Probably need to expand this and probably use a serial brute force like approach, but meh
16
# Lets just see if it works.
17
charset = [char for char in serial_number[-4:]]
18
charset.extend(['\x00', '\x10', 'H', 'T', 'B', 'P'])
19
possible_combinations = len(charset) * 16 * 16
20
21
22
# Credit http://stackoverflow.com/questions/11747254/python-brute-force-algorithm
23
def next_value():
24
    return (''.join(candidate)
25
            for candidate in itertools.chain.from_iterable(itertools.product(charset, repeat=i)
26
                                                           for i in range(16, 16 + 1)))
27
28
29
def counter_check(file_data, cipher, swap_data=False):
30
    counter_misses = 0
31
    counter_checks = 0
32
    last_counter = 0
33
    for line in file_data:
34
        data = line.split(',')[1:]
35
        data = [int(value, 2) for value in data]
36
        data = ''.join(map(chr, data))
37
        if not swap_data:
38
            decrypted = cipher.decrypt(data[:16]) + cipher.decrypt(data[16:])
39
        else:
40
            decrypted = cipher.decrypt(data[16:]) + cipher.decrypt(data[:16])
41
        counter = ord(decrypted[0])
42
        # Uncomment this
43
        # print(counter)
44
        if counter <= 127:
45
            if counter != last_counter + 1:
46
                counter_misses += 1
47
        elif not (counter == 0 and last_counter > 127):
48
            counter_misses += 1
49
        if counter_misses > 2 and counter_checks > 16:
50
            return False
51
        if counter_checks > 16 and counter_misses < 2:
52
            return True
53
        counter_checks += 1
54
        last_counter = counter
55
56
57
with open('{}'.format(filename), 'r') as encrypted_data:
58
    file_data = encrypted_data.readlines()
59
60
61
def check_key(next_check):
62
    new_cipher = AES.new(''.join(next_check), AES.MODE_ECB, iv)
63
    if counter_check(file_data, new_cipher):
64
        print("Correct Key Found! {}".format(next_check))
65
        sys.exit()
66
67
68
pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1)
69
70
i = 0
71
last_i = 1
72
then = datetime.now()
73
for key in next_value():
74
    pool.apply_async(check_key, args=(key,))
75
    i += 1
76
77
    now = datetime.now()
78
    if now - then > timedelta(minutes=1):
79
        print("{} keys per second, last key {}".format((i - last_i) / 60, key))
80
        last_i = i
81
        then = now
82
    time.sleep(0.00001)
83
84
print("No good.")