首页 > 解决方案 > 使用 pycrypto 实现 XML 加密以解析 LCP 编码的文件

问题描述

我正在尝试在 Python 中实现LCP DRM,但我无法理解其初始加密过程中的数据流。

license.lcpl他们文件的关键部分是

{                                                                                                    
    "provider":"http://www.epagine.fr",                                                              
    "id":"6666065a-e7bd-44b4-93ad-abd0336374dd",                                                     
    "issued":"....",                                                                 
    "encryption":                                                                                    
    {                                                                                                
        "profile":"http://readium.org/lcp/profile-1.0",                                              
        "content_key":{                                                                              
            "algorithm":"http://www.w3.org/2001/04/xmlenc#aes256-cbc",                               
            "encrypted_value":"itxQlsi5sxcSZ89eW2m80UCOyEDqBZzgTX3E/kG3rqWstvnFXOqOXVwiodlHUmtUSqxdbToy02fubOSt1/37AQ=="
        },                                                                                           
        "user_key":{                                                                                 
            "algorithm":"http://www.w3.org/2001/04/xmlenc#sha256",                                   
            "text_hint":"Quelle est votre Clé LCP ?",
 "key_check":"pFoXDupsQReQ5H5e9Vg6JtHkjkbVkOlkGYUWvWmFSgfZN8anAyMP7T6+zW3FJn+GzQpatvRQW7W54wixrUeorQ=="}

    },         

这意味着 - 我相信 - 供应商发布的User Passphrase 4EeffRhPz6(或者这可能是 256 位User Key?)应该散列到长度为 256 位的某个 User Key值 H。然后我应该能够从key_check字段中的数据中提取 AES 初始化向量,并使用 AES256-CBC 将其加密id 6666065a-e7bd-44b4-93ad-abd0336374ddkey_check. 完成后,我应该使用逆过程来解密内容密钥,然后使用内容密钥来解密我的文件。(来自示例文件的数据在底部给出。)

我相信 H 的相关值是VDDcCeWkbZlZnjc5yJ+L0YDJqgvF480ej2cnqw3qMhE=,IV 应该是pFoXDupsQReQ5H5e9Vg6Jg==。但我不确定,也无法复制该key_check领域。我一直在使用该pycrypto库并将所有内容都转换为字节,然后再将它们作为参数传递。

我的一些作品:

In [142]: from Crypto.Hash import SHA256, AES
In [143]: h = SHA256.new()
In [144]: h.update(b'4EeffRhPz6')
In [146]: h.digest()
Out[146]: b"T0\xdc\t\xe5\xa4m\x99Y\x9e79\xc8\x9f\x8b\xd1\x80\xc9\xaa\x0b\xc5\xe3\xcd\x1e\x8fg'\xab\r\xea2\x11"

In [147]: codecs.encode(h.digest(),'base64')
Out[147]: b'VDDcCeWkbZlZnjc5yJ+L0YDJqgvF480ej2cnqw3qMhE=\n'

In [148]: ciphertext = codecs.decode(b'itxQlsi5sxcSZ89eW2m80UCOyEDqBZzgTX3E/kG3rqWstvnFXOqOXVwiodlHUmtUSqxdbToy02fubOSt1/37AQ==','base64')
In [149]: key_check = codecs.decode(b"pFoXDupsQReQ5H5e9Vg6JtHkjkbVkOlkGYUWvWmFSgfZN8anAyMP7T6+zW3FJn+GzQpatvRQW7W54wixrUeorQ==",'base64')
In [150]: iv = key_check[:16]
In [151]: user_key_bytes = h.digest()
In [152]: aes_obj = AES.new(user_key_bytes, AES.MODE_CBC, iv)

In [153]: codecs.encode(aes_obj.encrypt(id_field.replace('-','')),'base64')
Out[153]: b'uTP9Z7ykqxS5xnpwafgxE12KBd5HuHdPARE2Qa64OsI=\n'

In [154]: codecs.encode(iv + aes_obj.encrypt(id_field.replace('-','')),'base64')
Out[154]: b'pFoXDupsQReQ5H5e9Vg6Jifk96zVYc4Ast38IQfR6z6sMqUxrTTbNEwQVJRxT2S6\n' # wrong

的内容,在加密前c01_cover.xhtml被压缩Deflate过,原来有 792 字节:

CJIqkyl4gAsQjaKJo8+D5imSgTc4jEJdm+xHmKr0kV/Nyyf87OclI+1hUCsXuvp42gSZOgSLejjVek3wguvE/4XBE6Mq/KWcAeoXbB/mMYMyQD66QfpL1j5tWPo/kSFVt8TNVebcvUQRCY43VkmEAryjmpg1CzLJIDfJrJqmfeHYO5uP5kOV5xL+dF4NQCPCFdvRExF1X+XprMoq7Cj1BMNyUfUBMVx1Z8emKBBaW+AkSVJIw3cjSJdeTo0hBzm/7Qu78YwkA184fLTtEQ0dD3HzzkvMfL052i0mJT6cSR/LVWt7BZTbxRVf7s6fvjhK4LYT8arLNIvKy7UianJIngn3MRUFXexs7rLPrhw5nXDazexEh3rWzGTBxHBySL1ldjs2cvlc0BKhpCyWfGGbaEPZl1mHt7tIHQhO5oHHl079K1t/oL2Q5FJ6RdCnKIL9sxbPMcFnmPZFyVE0GK6Ucx1KiaC8xoQirEJWDB7iTniwp8Vl/t/HeHUh+/nbVdx6ohQm10lxmOoRTMtYAUo7kg==

任何想法,将不胜感激!

标签: pythonencryptionpycryptodrm

解决方案


推荐阅读