Try to fix B&N issues

This commit is contained in:
NoDRM 2022-01-02 16:23:36 +01:00
parent a275d5d819
commit d5473f1db0
3 changed files with 46 additions and 29 deletions

View File

@ -328,8 +328,7 @@ class DeDRM(FileTypePlugin):
# Attempt to decrypt epub with each encryption key (generated or provided). # Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['bandnkeys'].items(): for keyname, userkey in dedrmprefs['bandnkeys'].items():
keyname_masked = "".join(("X" if (x.isdigit()) else x) for x in keyname) print("{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname))
print("{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked))
of = self.temporary_file(".epub") of = self.temporary_file(".epub")
# Give the user key, ebook and TemporaryPersistent file to the decryption function. # Give the user key, ebook and TemporaryPersistent file to the decryption function.
@ -347,7 +346,7 @@ class DeDRM(FileTypePlugin):
# Return the modified PersistentTemporary file to calibre. # Return the modified PersistentTemporary file to calibre.
return self.postProcessEPUB(of.name) return self.postProcessEPUB(of.name)
print("{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)) print("{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime))
# perhaps we should see if we can get a key from a log file # perhaps we should see if we can get a key from a log file
print("{0} v{1}: Looking for new NOOK Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)) print("{0} v{1}: Looking for new NOOK Keys after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
@ -358,6 +357,7 @@ class DeDRM(FileTypePlugin):
###### Add keys from the NOOK Study application (ignoblekeyNookStudy.py) ###### Add keys from the NOOK Study application (ignoblekeyNookStudy.py)
try: try:
defaultkeys_study = []
if iswindows or isosx: if iswindows or isosx:
from ignoblekeyNookStudy import nookkeys from ignoblekeyNookStudy import nookkeys
@ -376,6 +376,7 @@ class DeDRM(FileTypePlugin):
###### Add keys from the NOOK Microsoft Store application (ignoblekeyNookStudy.py) ###### Add keys from the NOOK Microsoft Store application (ignoblekeyNookStudy.py)
try: try:
defaultkeys_store = []
if iswindows: if iswindows:
# That's a Windows store app, it won't run on Linux or MacOS anyways. # That's a Windows store app, it won't run on Linux or MacOS anyways.
# No need to waste time running Wine. # No need to waste time running Wine.
@ -389,12 +390,14 @@ class DeDRM(FileTypePlugin):
###### Add keys from Adobe PassHash ADE activation data (adobekey_get_passhash.py) ###### Add keys from Adobe PassHash ADE activation data (adobekey_get_passhash.py)
try: try:
defaultkeys_ade = []
if iswindows: if iswindows:
# Right now this is only implemented for Windows. MacOS support still needs to be added. # Right now this is only implemented for Windows. MacOS support still needs to be added.
from adobekey_get_passhash import passhash_keys from adobekey_get_passhash import passhash_keys
defaultkeys_ade, names = passhash_keys() defaultkeys_ade, names = passhash_keys()
if isosx: if isosx:
print("{0} v{1}: Dumping ADE PassHash data is not yet supported on MacOS.".format(PLUGIN_NAME, PLUGIN_VERSION)) print("{0} v{1}: Dumping ADE PassHash data is not yet supported on MacOS.".format(PLUGIN_NAME, PLUGIN_VERSION))
defaultkeys_ade = []
except: except:
print("{0} v{1}: Exception when getting PassHashes from ADE after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)) print("{0} v{1}: Exception when getting PassHashes from ADE after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
traceback.print_exc() traceback.print_exc()
@ -419,6 +422,11 @@ class DeDRM(FileTypePlugin):
if len(newkeys) > 0: if len(newkeys) > 0:
try: try:
for i,userkey in enumerate(newkeys): for i,userkey in enumerate(newkeys):
if len(userkey) == 0:
print("{0} v{1}: Skipping empty key.".format(PLUGIN_NAME, PLUGIN_VERSION))
continue
print("{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION)) print("{0} v{1}: Trying a new default key".format(PLUGIN_NAME, PLUGIN_VERSION))
of = self.temporary_file(".epub") of = self.temporary_file(".epub")
@ -451,10 +459,14 @@ class DeDRM(FileTypePlugin):
return self.postProcessEPUB(of.name) return self.postProcessEPUB(of.name)
print("{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)) print("{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
return inf.name
except: except:
pass pass
# Looks like we were unable to decrypt the book ...
return inf.name
else: else:
# This is a "normal" Adobe eBook. # This is a "normal" Adobe eBook.
@ -611,17 +623,13 @@ class DeDRM(FileTypePlugin):
pass pass
# Something went wrong with decryption. # Something went wrong with decryption.
print("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)) print("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)) raise DeDRMError("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
# Not a Barnes & Noble nor an Adobe Adept # Not a Barnes & Noble nor an Adobe Adept
# Probably a DRM-free EPUB, but we should still check for fonts. # Probably a DRM-free EPUB, but we should still check for fonts.
print("{0} v{1}: “{2}” is neither an Adobe Adept nor a Barnes & Noble encrypted ePub".format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))
return self.postProcessEPUB(inf.name)
#raise DeDRMError("{0} v{1}: Couldn't decrypt after {2:.1f} seconds. DRM free perhaps?".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
# No DRM?
return self.postProcessEPUB(inf.name) return self.postProcessEPUB(inf.name)
@ -776,8 +784,7 @@ class DeDRM(FileTypePlugin):
# Unable to decrypt the PDF with any of the existing keys. Is it a B&N PDF? # Unable to decrypt the PDF with any of the existing keys. Is it a B&N PDF?
# Attempt to decrypt PDF with each encryption key (generated or provided). # Attempt to decrypt PDF with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['bandnkeys'].items(): for keyname, userkey in dedrmprefs['bandnkeys'].items():
keyname_masked = "".join(("X" if (x.isdigit()) else x) for x in keyname) print("{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname))
print("{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked))
of = self.temporary_file(".pdf") of = self.temporary_file(".pdf")
# Give the user key, ebook and TemporaryPersistent file to the decryption function. # Give the user key, ebook and TemporaryPersistent file to the decryption function.
@ -951,8 +958,8 @@ class DeDRM(FileTypePlugin):
pass pass
if not decoded: if not decoded:
#if you reached here then no luck raise and exception #if you reached here then no luck raise and exception
print("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)) print("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)) raise DeDRMError("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
of = self.temporary_file(book.getBookExtension()) of = self.temporary_file(book.getBookExtension())
book.getFile(of.name) book.getFile(of.name)
@ -969,8 +976,7 @@ class DeDRM(FileTypePlugin):
dedrmprefs = prefs.DeDRM_Prefs() dedrmprefs = prefs.DeDRM_Prefs()
# Attempt to decrypt epub with each encryption key (generated or provided). # Attempt to decrypt epub with each encryption key (generated or provided).
for keyname, userkey in dedrmprefs['ereaderkeys'].items(): for keyname, userkey in dedrmprefs['ereaderkeys'].items():
keyname_masked = "".join(("X" if (x.isdigit()) else x) for x in keyname) print("{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname))
print("{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked))
of = self.temporary_file(".pmlz") of = self.temporary_file(".pmlz")
# Give the userkey, ebook and TemporaryPersistent file to the decryption function. # Give the userkey, ebook and TemporaryPersistent file to the decryption function.
@ -981,13 +987,13 @@ class DeDRM(FileTypePlugin):
# Decryption was successful return the modified PersistentTemporary # Decryption was successful return the modified PersistentTemporary
# file to Calibre's import process. # file to Calibre's import process.
if result == 0: if result == 0:
print("{0} v{1}: Successfully decrypted with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)) print("{0} v{1}: Successfully decrypted with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime))
return of.name return of.name
print("{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)) print("{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime))
print("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)) print("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
raise DeDRMError("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)) raise DeDRMError("{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at noDRM's repository: https://github.com/noDRM/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
def run(self, path_to_ebook): def run(self, path_to_ebook):

View File

@ -75,6 +75,8 @@ if iswindows:
plkroot = winreg.OpenKey(cuser, PRIVATE_LICENCE_KEY_PATH) plkroot = winreg.OpenKey(cuser, PRIVATE_LICENCE_KEY_PATH)
except WindowsError: except WindowsError:
raise ADEPTError("Could not locate ADE activation") raise ADEPTError("Could not locate ADE activation")
except FileNotFoundError:
raise ADEPTError("Could not locate ADE activation")
idx = 1 idx = 1
@ -100,6 +102,8 @@ if iswindows:
plkkey = winreg.OpenKey(plkparent, "%04d" % (j,)) plkkey = winreg.OpenKey(plkparent, "%04d" % (j,))
except WindowsError: except WindowsError:
break break
except FileNotFoundError:
break
ktype = winreg.QueryValueEx(plkkey, None)[0] ktype = winreg.QueryValueEx(plkkey, None)[0]
if ktype == 'fingerprint': if ktype == 'fingerprint':
fp = winreg.QueryValueEx(plkkey, 'value')[0] fp = winreg.QueryValueEx(plkkey, 'value')[0]
@ -118,6 +122,8 @@ if iswindows:
plkkey = winreg.OpenKey(plkparent, "%04d" % (j,)) plkkey = winreg.OpenKey(plkparent, "%04d" % (j,))
except WindowsError: except WindowsError:
break break
except FileNotFoundError:
break
ktype = winreg.QueryValueEx(plkkey, None)[0] ktype = winreg.QueryValueEx(plkkey, None)[0]
if ktype == 'operatorURL': if ktype == 'operatorURL':
operatorURL = winreg.QueryValueEx(plkkey, 'value')[0] operatorURL = winreg.QueryValueEx(plkkey, 'value')[0]
@ -135,6 +141,8 @@ if iswindows:
plkkey = winreg.OpenKey(plkparent, "%04d" % (j,)) plkkey = winreg.OpenKey(plkparent, "%04d" % (j,))
except WindowsError: except WindowsError:
break break
except FileNotFoundError:
break
ktype = winreg.QueryValueEx(plkkey, None)[0] ktype = winreg.QueryValueEx(plkkey, None)[0]
if ktype == "passHash": if ktype == "passHash":

View File

@ -521,6 +521,15 @@ def decryptBook(userkey, inpath, outpath):
# Normal Adobe ADEPT # Normal Adobe ADEPT
rsa = RSA(userkey) rsa = RSA(userkey)
bookkey = rsa.decrypt(base64.b64decode(bookkey.encode('ascii'))) bookkey = rsa.decrypt(base64.b64decode(bookkey.encode('ascii')))
# Verify key:
if len(bookkey) > 16:
# Padded as per RSAES-PKCS1-v1_5
if verify_book_key(bookkey):
bookkey = bookkey[-16:]
else:
print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
return 2
else: else:
# Adobe PassHash / B&N # Adobe PassHash / B&N
key = base64.b64decode(userkey)[:16] key = base64.b64decode(userkey)[:16]
@ -533,14 +542,8 @@ def decryptBook(userkey, inpath, outpath):
bookkey = bookkey[:-pad] bookkey = bookkey[:-pad]
# Padded as per RSAES-PKCS1-v1_5
if len(bookkey) > 16: if len(bookkey) > 16:
if verify_book_key(bookkey):
bookkey = bookkey[-16:] bookkey = bookkey[-16:]
else:
print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
return 2
encryption = inf.read('META-INF/encryption.xml') encryption = inf.read('META-INF/encryption.xml')
decryptor = Decryptor(bookkey, encryption) decryptor = Decryptor(bookkey, encryption)