'''
count = 503
- password = 'Thomsun was here!'
+ password = b'Thomsun was here!'
def __init__(self, salt):
key = self.password + salt
obfuscation = AndroidObfuscation()
def get_value(key):
- encrypted_key = obfuscation.encrypt(key)
+ encrypted_key = obfuscation.encrypt(a2b_hex(key))
encrypted_value = storage.get(encrypted_key)
if encrypted_value:
return obfuscation.decrypt(encrypted_value)
import sqlite3
connection = sqlite3.connect(path)
cursor = connection.cursor()
- cursor.execute('''select userdata_value from userdata where userdata_key like '%/%token.device.deviceserialname%' ''')
- userdata_keys = cursor.fetchall()
+ cursor.execute('''select device_data_value from device_data where device_data_key like '%serial.number%' ''')
+ device_data_keys = cursor.fetchall()
dsns = []
- for userdata_row in userdata_keys:
+ for device_data_row in device_data_keys:
try:
- if userdata_row and userdata_row[0]:
- userdata_utf8 = userdata_row[0].encode('utf8')
- if len(userdata_utf8) > 0:
- dsns.append(userdata_utf8)
+ if device_data_row and device_data_row[0]:
+ if len(device_data_row[0]) > 0:
+ dsns.append(device_data_row[0])
except:
print("Error getting one of the device serial name keys")
traceback.print_exc()
for userdata_row in userdata_keys:
try:
if userdata_row and userdata_row[0]:
- userdata_utf8 = userdata_row[0].encode('utf8')
- if len(userdata_utf8) > 0:
- tokens.append(userdata_utf8)
+ if len(userdata_row[0]) > 0:
+ if ',' in userdata_row[0]:
+ splits = userdata_row[0].split(',')
+ for split in splits:
+ tokens.append(split)
+ tokens.append(userdata_row[0])
except:
print("Error getting one of the account token keys")
traceback.print_exc()
serials = []
for x in dsns:
- serials.append(x)
for y in tokens:
- serials.append('%s%s' % (x, y))
- for y in tokens:
- serials.append(y)
+ serials.append(x)
+ serials.append(y)
+ serials.append(x+y)
return serials
def get_serials(path=STORAGE):
try :
read = open(path, 'rb')
head = read.read(24)
- if head[:14] == 'ANDROID BACKUP':
+ if head[:14] == b'ANDROID BACKUP':
output = StringIO(zlib.decompress(read.read()))
except Exception:
pass
if len(keys) > 0:
with open(outfile, 'w') as keyfileout:
for key in keys:
- keyfileout.write(key)
+ keyfileout.write(b2a_hex(key))
keyfileout.write("\n")
return True
return False
# Python 3, September 2020
# Standard Python modules.
-import os, traceback, json, binascii
+import os, traceback, json, codecs
from PyQt5.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
QGroupBox, QPushButton, QListWidget, QListWidgetItem,
with open(fpath,'rb') as keyfile:
new_key_value = keyfile.read()
if self.binary_file:
- new_key_value = binascii.b2a_hex(new_key_value)
+ new_key_value = codecs.encode(new_key_value,'hex')
elif self.json_file:
new_key_value = json.loads(new_key_value)
elif self.android_file:
if filename:
if self.binary_file:
with open(filename, 'wb') as fname:
- fname.write(binascii.a2b_hex(self.plugin_keys[keyname]))
+ fname.write(codecs.decode(self.plugin_keys[keyname],'hex'))
elif self.json_file:
with open(filename, 'w') as fname:
fname.write(json.dumps(self.plugin_keys[keyname]))
elif self.android_file:
with open(filename, 'w') as fname:
for key in self.plugin_keys[keyname]:
- fname.write(key.decode('utf-8'))
+ fname.write(key)
fname.write('\n')
else:
with open(filename, 'w') as fname:
- fname.write(self.plugin_keys[keyname].decode('utf-8'))
+ fname.write(self.plugin_keys[keyname])
@property
def key_value(self):
from calibre_plugins.dedrm.erdr2pml import getuser_key as generate_ereader_key
- return binascii.b2a_hex(generate_ereader_key(self.user_name, self.cc_number))
+ return codecs.encode(generate_ereader_key(self.user_name, self.cc_number),'hex')
@property
def user_name(self):
@property
def key_value(self):
- return binascii.b2a_hex(self.default_key)
+ return codecs.encode(self.default_key,'hex')
def accept(self):
print(" It's enough to enter the last 8 digits of the credit card number")
return
-def getuser_key(name, cc):
+def getuser_key(name,cc):
newname = "".join(c for c in name.lower() if c >= 'a' and c <= 'z' or c >= '0' and c <= '9')
cc = cc.replace(" ","")
return struct.pack('>LL', binascii.crc32(bytes(newname.encode('utf-8'))) & 0xffffffff, binascii.crc32(bytes(cc[-8:].encode('utf-8'))) & 0xffffffff)
elif len(args)==4:
infile, outpath, name, cc = args
- print(binascii.b2a_hex(getuser_key(name, cc)))
+ print(binascii.b2a_hex(getuser_key(name,cc)))
- return decryptBook(infile, outpath, make_pmlz, getuser_key(name, cc))
+ return decryptBook(infile, outpath, make_pmlz, getuser_key(name,cc))
if __name__ == "__main__":
def _load_crypto_pycrypto():
from Crypto.Cipher import AES as _AES
from Crypto.PublicKey import RSA as _RSA
+ from Crypto.Cipher import PKCS1_v1_5 as _PKCS1_v1_5
# ASN.1 parsing code from tlslite
class ASN1Error(Exception):
class AES(object):
def __init__(self, key):
- self._aes = _AES.new(key, _AES.MODE_CBC, '\x00'*16)
+ self._aes = _AES.new(key, _AES.MODE_CBC, b'\x00'*16)
def decrypt(self, data):
return self._aes.decrypt(data)
class RSA(object):
def __init__(self, der):
- key = ASN1Parser([ord(x) for x in der])
+ key = ASN1Parser([x for x in der])
key = [key.getChild(x).value for x in range(1, 4)]
key = [self.bytesToNumber(v) for v in key]
self._rsa = _RSA.construct(key)
return total
def decrypt(self, data):
- return self._rsa.decrypt(data)
+ return _PKCS1_v1_5.new(self._rsa).decrypt(data, 172)
return (AES, RSA)
return 1
bookkey = rsa.decrypt(codecs.decode(bookkey.encode('ascii'), 'base64'))
# Padded as per RSAES-PKCS1-v1_5
- if bookkey[-17] != '\x00' and bookkey[-17] != 0:
- print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
- return 2
+ if len(bookkey) != 16:
+ if bookkey[-17] != '\x00' and bookkey[-17] != 0:
+ print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
+ return 2
+ else:
+ bookkey = bookkey[-16:]
encryption = inf.read('META-INF/encryption.xml')
- decryptor = Decryptor(bookkey[-16:], encryption)
+ decryptor = Decryptor(bookkey, encryption)
kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
zi = ZipInfo('mimetype')
def gui_main():
try:
import tkinter
- import tkinter_constants
- import tkinter_filedialog
- import tkinter_messagebox
+ import tkinter.constants
+ import tkinter.filedialog
+ import tkinter.messagebox
import traceback
except:
return cli_main()
def __init__(self, root):
tkinter.Frame.__init__(self, root, border=5)
self.status = tkinter.Label(self, text="Select files for decryption")
- self.status.pack(fill=tkinter_constants.X, expand=1)
+ self.status.pack(fill=tkinter.constants.X, expand=1)
body = tkinter.Frame(self)
- body.pack(fill=tkinter_constants.X, expand=1)
- sticky = tkinter_constants.E + tkinter_constants.W
+ body.pack(fill=tkinter.constants.X, expand=1)
+ sticky = tkinter.constants.E + tkinter.constants.W
body.grid_columnconfigure(1, weight=2)
tkinter.Label(body, text="Key file").grid(row=0)
self.keypath = tkinter.Entry(body, width=30)
buttons.pack()
botton = tkinter.Button(
buttons, text="Decrypt", width=10, command=self.decrypt)
- botton.pack(side=tkinter_constants.LEFT)
- tkinter.Frame(buttons, width=10).pack(side=tkinter_constants.LEFT)
+ botton.pack(side=tkinter.constants.LEFT)
+ tkinter.Frame(buttons, width=10).pack(side=tkinter.constants.LEFT)
button = tkinter.Button(
buttons, text="Quit", width=10, command=self.quit)
- button.pack(side=tkinter_constants.RIGHT)
+ button.pack(side=tkinter.constants.RIGHT)
def get_keypath(self):
- keypath = tkinter_filedialog.askopenfilename(
+ keypath = tkinter.filedialog.askopenfilename(
parent=None, title="Select Adobe Adept \'.der\' key file",
defaultextension=".der",
filetypes=[('Adobe Adept DER-encoded files', '.der'),
('All Files', '.*')])
if keypath:
keypath = os.path.normpath(keypath)
- self.keypath.delete(0, tkinter_constants.END)
+ self.keypath.delete(0, tkinter.constants.END)
self.keypath.insert(0, keypath)
return
def get_inpath(self):
- inpath = tkinter_filedialog.askopenfilename(
+ inpath = tkinter.filedialog.askopenfilename(
parent=None, title="Select ADEPT-encrypted ePub file to decrypt",
defaultextension=".epub", filetypes=[('ePub files', '.epub')])
if inpath:
inpath = os.path.normpath(inpath)
- self.inpath.delete(0, tkinter_constants.END)
+ self.inpath.delete(0, tkinter.constants.END)
self.inpath.insert(0, inpath)
return
def get_outpath(self):
- outpath = tkinter_filedialog.asksaveasfilename(
+ outpath = tkinter.filedialog.asksaveasfilename(
parent=None, title="Select unencrypted ePub file to produce",
defaultextension=".epub", filetypes=[('ePub files', '.epub')])
if outpath:
outpath = os.path.normpath(outpath)
- self.outpath.delete(0, tkinter_constants.END)
+ self.outpath.delete(0, tkinter.constants.END)
self.outpath.insert(0, outpath)
return
if decrypt_status == 0:
self.status['text'] = "File successfully decrypted"
else:
- self.status['text'] = "The was an error decrypting the file."
+ self.status['text'] = "There was an error decrypting the file."
root = tkinter.Tk()
root.title("Adobe Adept ePub Decrypter v.{0}".format(__version__))
root.resizable(True, False)
root.minsize(300, 0)
- DecryptionDialog(root).pack(fill=tkinter_constants.X, expand=1)
+ DecryptionDialog(root).pack(fill=tkinter.constants.X, expand=1)
root.mainloop()
return 0
# Standard Python modules.
import os, sys, re, hashlib
-import json
+import codecs, json
import traceback
from calibre.utils.config import dynamic, config_dir, JSONConfig
name, cc = keystring.split(',')
# Generate eReader user key from name and credit card number.
keyname = "{0}_{1}".format(name.strip(),cc.strip()[-4:])
- keyvalue = getuser_key(name,cc).encode('hex')
+ keyvalue = codecs.encode(getuser_key(name,cc),'hex')
userkeys.append([keyname,keyvalue])
except Exception as e:
traceback.print_exc()
key = os.path.splitext(filename)[0]
value = open(fpath, 'rb').read()
if encoding is not None:
- value = value.encode(encoding)
+ value = codecs.encode(value,encoding)
userkeys.append([key,value])
except:
traceback.print_exc()
# This is used to ensure paths in generated ZIP files always use
# forward slashes as the directory separator, as required by the
# ZIP format specification.
- if os.sep != "/" and os.sep in filename:
- filename = filename.replace(os.sep, "/")
+ if os.sep != "/" and os.sep.encode('utf-8') in filename:
+ filename = filename.replace(os.sep.encode('utf-8'), b"/")
self.filename = filename # Normalized file name
self.date_time = date_time # year, month, day, hour, min, sec