Quote:
Originally Posted by vila
It works!
The script first determines if the file is LCP-protected by searching for specific metadata files like META-INF/license.lcpl and META-INF/encryption.xml.
Code:
# From tryParseAsLCPType
if "id" in license and "encryption" in license and "profile" in license["encryption"]:
return ("epub", license)
Then to verify a password, the script needs to "transform" the user's input into a cryptographic key.
Code:
# From LCPTransform.secret_transform_profile20
blk = blake(masterkey, 64)
crc = crc32bts(blk)
adlr = adler32bts(blk)
strn = blk + crc + adlr
hmac = hmac256(adlr, strn)
return binascii.hexlify(hashlib.sha256(hmac).digest()).decode("latin-1")
The script then verifies if the transformed key is correct by attempting to decrypt a small piece of data called the key_check.
Code:
# From decryptLCPbook
decrypted = dataDecryptLCP(key_check, transformed_hash)
if (decrypted is not None and decrypted.decode("ascii", errors="ignore") == license["id"]):
correct_password_hash = transformed_hash
Finally, once the key is validated, the script uses it to decrypt the Content Key, which is then used to decrypt the actual ePub or PDF assets.
Code:
# From Decryptor.decrypt
aes = AES.new(self.book_key, AES.MODE_CBC, data[:16])
data = aes.decrypt(data[16:])
# Fix padding and decompress
data, was_decomp = self.decompress(data)
The data is decrypted using the AES Cipher Block Chaining (CBC) mode, where the first 16 bytes of the data serve as the Initialization Vector (IV). Finally, it also removes the padding and decompresses the content using zlib.
|
Also the "key" or passphrase in this case is your email (if you downloaded from the internet archive) or library card number (if you downloaded from a public library) or order number (if you got it from an online bookstore)