-
Notifications
You must be signed in to change notification settings - Fork 17
/
DecryptSeeds.py
101 lines (72 loc) · 2.96 KB
/
DecryptSeeds.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
import binascii
import getpass
import configparser
import sys
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Util import Counter
import SeedStorage
# Setup Config Parser
config = configparser.ConfigParser()
try:
config.read(r'./config.cfg')
except:
print("Please fill out a config.cfg file according to specifications.")
sys.exit()
try:
axieSalt = config.get('Encryption', 'salt')
if axieSalt == "" or axieSalt == "mysaltpleasechangeme" or len(axieSalt) > 1024:
raise Exception("Invalid salt")
except:
print("Please fill out an [Encryption] section with a salt property up to 1024 characters.")
sys.exit()
# Encryption methodology adopted from https://stackoverflow.com/a/44662262
# 32 bit keys => AES256 encryption
key_bytes = 32
# 32 bit key, binary plaintext string to encrypt, and IV binary string
def encrypt(key, plaintext, iv=None):
assert len(key) == key_bytes
# create random IV if one not provided
if iv is None:
iv = Random.new().read(AES.block_size)
# convert IV to integer
iv_int = int(binascii.hexlify(iv), 16)
# create counter using the IV
ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
# create cipher object
aes = AES.new(key, AES.MODE_CTR, counter=ctr)
# encrypt the string and return the IV/ciphertext
ciphertext = aes.encrypt(plaintext)
return iv, ciphertext
# 32 bit key, IV binary string, and ciphertext to decrypt
def decrypt(key, iv, ciphertext):
assert len(key) == key_bytes
# convert IV to integer and create counter using the IV
iv_int = int(binascii.hexlify(iv), 16)
ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
# create cipher object
aes = AES.new(key, AES.MODE_CTR, counter=ctr)
# decrypt ciphertext and return the decrypted binary string
plaintext = aes.decrypt(ciphertext)
return plaintext
print("You should only use this script if you are trying to decrypt your encrypted seeds to recover them from the SeedStorage. This will require your password and the original IV data file.")
print("If successful, it will print your seed phrases in plaintext to the screen for your recovery. Make sure your computer is secure, possible disconnected from the internet, before doing this.\n")
print("Note, the password field is hidden so it will not display what you type.")
password = getpass.getpass().strip()
print("\nGenerating key.\n")
key = PBKDF2(password, axieSalt, key_bytes)
with open("iv.dat", "rb") as f:
iv = f.read()
count = 1
for seed in SeedStorage.SeedList:
# print(f"Encrypted seed {count}: {seed}")
try:
res = decrypt(key, iv, seed).decode("utf8")
except:
print(f"Invalid decryption output detected for seed {count}, likely wrong password or corrupt IV data file.")
count += 1
continue
print(f"Seed {count}: {res}")
count += 1
print("\nDone.")