-
Notifications
You must be signed in to change notification settings - Fork 74
/
generate_keys.py
executable file
·177 lines (136 loc) · 5.02 KB
/
generate_keys.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/env python
import sys
import base64
import hashlib
import random
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend
import argparse
import shutil
import os
import string
from string import Template
import struct
OUTPUT_FOLDER = 'output/'
TEMPLATE = Template('{'
'\"id\": $id,'
'\"colorComponents\": ['
' 0,'
' 1,'
' 0,'
' 1'
'],'
'\"name\": \"$name\",'
'\"privateKey\": \"$privateKey\",'
'\"icon\": \"\",'
'\"isDeployed\": true,'
'\"colorSpaceName\": \"kCGColorSpaceExtendedSRGB\",'
'\"usesDerivation\": false,'
'\"isActive\": false,'
'\"additionalKeys\": [$additionalKeys]'
'}')
def int_to_bytes(n, length, endianess='big'):
h = '%x' % n
s = ('0'*(len(h) % 2) + h).zfill(length*2).decode('hex')
return s if endianess == 'big' else s[::-1]
def to_C_byte_array(adv_key, isV3):
out = '{'
for element in range(0, len(adv_key)):
e = adv_key[element] if isV3 else ord(adv_key[element])
out = out + "0x{:02x}".format(e)
if element != len(adv_key)-1:
out = out + ','
out = out + '}'
return out
def sha256(data):
digest = hashlib.new("sha256")
digest.update(data)
return digest.digest()
parser = argparse.ArgumentParser()
parser.add_argument(
'-n', '--nkeys', help='number of keys to generate', type=int, default=1)
parser.add_argument('-p', '--prefix', help='prefix of the keyfiles')
parser.add_argument(
'-y', '--yaml', help='yaml file where to write the list of generated keys')
parser.add_argument(
'-v', '--verbose', help='print keys as they are generated', action="store_true")
parser.add_argument(
'-tinfs', '--thisisnotforstalking', help=argparse.SUPPRESS)
args = parser.parse_args()
MAX_KEYS = 1
if (args.thisisnotforstalking == 'i_agree'):
MAX_KEYS = 50
if args.nkeys < 1 or args.nkeys > MAX_KEYS:
raise argparse.ArgumentTypeError(
"Number of keys out of range (between 1 and " + str(MAX_KEYS) + ")")
current_directory = os.getcwd()
final_directory = os.path.join(current_directory, OUTPUT_FOLDER)
if os.path.exists(OUTPUT_FOLDER):
shutil.rmtree(OUTPUT_FOLDER)
os.mkdir(final_directory)
prefix = ''
if args.prefix is None:
prefix = ''.join(random.choice(string.ascii_uppercase +
string.digits) for _ in range(6))
else:
prefix = args.prefix
if args.yaml:
yaml = open(OUTPUT_FOLDER + prefix + '_' + args.yaml + '.yaml', 'w')
yaml.write(' keys:\n')
keyfile = open(OUTPUT_FOLDER + prefix + '_keyfile', 'wb')
keyfile.write(struct.pack("B", args.nkeys))
devices = open(OUTPUT_FOLDER + prefix + '_devices.json', 'w')
devices.write('[\n')
fname = '%s.keys' % (prefix)
keys = open(OUTPUT_FOLDER + fname, 'w')
isV3 = sys.version_info.major > 2
print('Using python3' if isV3 else 'Using python2')
print(f'Output will be written to {OUTPUT_FOLDER}')
additionalKeys = []
i = 0
while i < args.nkeys:
priv = random.getrandbits(224)
adv = ec.derive_private_key(priv, ec.SECP224R1(
), default_backend()).public_key().public_numbers().x
if isV3:
priv_bytes = priv.to_bytes(28, 'big')
adv_bytes = adv.to_bytes(28, 'big')
else:
priv_bytes = int_to_bytes(priv, 28)
adv_bytes = int_to_bytes(adv, 28)
priv_b64 = base64.b64encode(priv_bytes).decode("ascii")
adv_b64 = base64.b64encode(adv_bytes).decode("ascii")
s256_b64 = base64.b64encode(sha256(adv_bytes)).decode("ascii")
if '/' in s256_b64[:7]:
print(
'Key skipped and regenerated, because there was a / in the b64 of the hashed pubkey :(')
continue
else:
i += 1
keyfile.write(base64.b64decode(adv_b64))
if i < args.nkeys:
additionalKeys.append(priv_b64) # The last one is the leading one
if args.verbose:
print('%d)' % (i+1))
print('Private key: %s' % priv_b64)
print('Advertisement key: %s' % adv_b64)
print('Hashed adv key: %s' % s256_b64)
if '/' in s256_b64[:7]:
print(
'no key file written, there was a / in the b64 of the hashed pubkey :(')
else:
keys.write('Private key: %s\n' % priv_b64)
keys.write('Advertisement key: %s\n' % adv_b64)
keys.write('Hashed adv key: %s\n' % s256_b64)
if args.yaml:
yaml.write(' - "%s"\n' % adv_b64)
addKeysS = ''
if (len(additionalKeys) > 0):
addKeysS = "\"" + "\",\"".join(additionalKeys) + "\""
devices.write(TEMPLATE.substitute(name=prefix,
id=str(random.choice(
range(0, 10000000))),
privateKey=priv_b64,
additionalKeys=addKeysS
))
devices.write(']')