Skip to content

Commit f2ffb28

Browse files
author
chren
committed
added password reader
1 parent dd0515e commit f2ffb28

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

slip-0016/pwdreader.py

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python2
2+
3+
from trezorlib.client import TrezorClient
4+
from trezorlib.transport_hid import HidTransport
5+
from binascii import hexlify, unhexlify
6+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
7+
from cryptography.hazmat.backends import default_backend
8+
import hmac, hashlib, base58, json, sys
9+
10+
11+
#return path by BIP-32
12+
def getPath():
13+
return client.expand_path("10016'/0");
14+
15+
#Deriving master key
16+
def getMasterKey():
17+
bip32_path = getPath()
18+
ENC_KEY = "Activate TREZOR Password Manager?"
19+
ENC_VALUE = unhexlify("2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee")
20+
key = hexlify(client.encrypt_keyvalue(
21+
bip32_path,
22+
ENC_KEY,
23+
ENC_VALUE,
24+
True,
25+
True
26+
))
27+
return key;
28+
29+
#Deriving file name and encryption key
30+
def getFileEncKey(key):
31+
filekey, enckey = key[:len(key)/2], key[len(key)/2:]
32+
FILENAME_MESS = "5f91add3fa1c3c76e90c90a3bd0999e2bd7833d06a483fe884ee60397aca277a"
33+
digest = hmac.new(filekey, FILENAME_MESS, hashlib.sha256).hexdigest()
34+
filename = ''.join((digest, '.pswd'))
35+
return [filename, filekey, enckey];
36+
37+
#Path to locally stored file
38+
def getFilePath():
39+
return '/home/chren/';
40+
41+
#File level decryption and file reading
42+
def decryptStorage(path, key):
43+
cipherkey = unhexlify(key)
44+
with open(path, "rb") as f:
45+
iv = f.read(12)
46+
tag = f.read(16)
47+
cipher = Cipher(algorithms.AES(cipherkey), modes.GCM(iv, tag), backend=default_backend())
48+
decryptor = cipher.decryptor()
49+
data = "";
50+
while True:
51+
block = f.read(16)
52+
# data are not authenticated yet
53+
if block:
54+
data = data + decryptor.update(block)
55+
else:
56+
break
57+
# throws exception when the tag is wrong
58+
data = data + decryptor.finalize()
59+
return json.loads(data);
60+
61+
def decryptEntryValue(nonce, val):
62+
cipherkey = unhexlify(nonce)
63+
iv = val[:12]
64+
tag = val[12:28]
65+
cipher = Cipher(algorithms.AES(cipherkey), modes.GCM(iv, tag), backend=default_backend())
66+
decryptor = cipher.decryptor()
67+
data = "";
68+
inputData = val[28:]
69+
while True:
70+
block = inputData[:16]
71+
inputData = inputData[16:]
72+
if block:
73+
data = data + decryptor.update(block)
74+
else:
75+
break
76+
# throws exception when the tag is wrong
77+
data = data + decryptor.finalize()
78+
return json.loads(data);
79+
80+
#decrypt give entry nonce
81+
def getDecryptedNonce(entry):
82+
print '\nWaiting for TREZOR input!\n'
83+
ENC_KEY = ''.join(('Unlock ', entry['title'], ' for user ', entry['username'], '?'))
84+
ENC_VALUE = entry['nonce']
85+
decrypted_nonce = hexlify(client.decrypt_keyvalue(
86+
getPath(),
87+
ENC_KEY,
88+
unhexlify(ENC_VALUE),
89+
False,
90+
True
91+
))
92+
return decrypted_nonce;
93+
94+
#list whatever
95+
def printList(obj, val):
96+
objList = obj[val]
97+
print '\n'
98+
print 'Entry list:'
99+
for x in xrange (len(objList)):
100+
keys = objList[str(x)].keys()
101+
print 'Entry id ', x
102+
for y in xrange (len(keys)):
103+
print keys[y],': ',objList[str(x)][keys[y]]
104+
print '\n'
105+
return;
106+
107+
108+
def main():
109+
masterKey = getMasterKey()
110+
#print 'master key: ', masterKey
111+
112+
fileName = getFileEncKey(masterKey)[0]
113+
#print 'file name: ', fileName
114+
115+
path = getFilePath()
116+
#print 'path to file: ', path
117+
118+
encKey = getFileEncKey(masterKey)[2]
119+
#print 'enckey: ', encKey
120+
121+
full_path = ''.join((path, fileName))
122+
parsed_json = decryptStorage(full_path, encKey)
123+
124+
#list entries
125+
printList(parsed_json, 'entries')
126+
entries = parsed_json['entries']
127+
128+
entry_id = raw_input('Select entry number to decrypt: ')
129+
130+
plain_nonce = getDecryptedNonce(entries[str(entry_id)])
131+
132+
133+
pwdArr = entries[str(entry_id)]['password']['data']
134+
pwdHex = ''.join([ hex(x)[2:].zfill(2) for x in pwdArr ])
135+
print 'password : ', decryptEntryValue(plain_nonce, unhexlify(pwdHex))
136+
137+
safeNoteArr = entries[str(entry_id)]['safe_note']['data']
138+
safeNoteHex = ''.join([ hex(x)[2:].zfill(2) for x in safeNoteArr ])
139+
print 'safe_note : ', decryptEntryValue(plain_nonce, unhexlify(safeNoteHex))
140+
return;
141+
142+
if __name__ == "__main__":
143+
try:
144+
# init Trezor transport
145+
client = TrezorClient(HidTransport(HidTransport.enumerate()[0]))
146+
except:
147+
print 'TREZOR is not plugged in. Please, connect TREZOR and retry.'
148+
else:
149+
main()

0 commit comments

Comments
 (0)