Python 2 - 解密Java的PBEWithMD5AndDES

时间:2014-10-02 12:40:57

标签: python python-2.7 encryption md5 des

这个问题与此问题有关:Replicate Java's PBEWithMD5AndDES in Python 2.7

<小时/> 这就是问题的答案(Python代码):

from Crypto.Hash import MD5
from Crypto.Cipher import DES

_password = 'q1w2e3r4t5y6'
_salt = '\x80\x40\xe0\x10\xf8\x04\xfe\x01'
_iterations = 50

if "__main__" == __name__:

    """Mimic Java's PBEWithMD5AndDES algorithm to produce a DES key"""
    print "Enter the password to encrypt:",
    plaintext_to_encrypt = raw_input()

    hasher = MD5.new()
    hasher.update(_password)
    hasher.update(_salt)
    result = hasher.digest()

    for i in range(1, _iterations):
        hasher = MD5.new()
        hasher.update(result)
        result = hasher.digest()

    # Pad plaintext per RFC 2898 Section 6.1
    padding = 8 - len(plaintext_to_encrypt) % 8
    plaintext_to_encrypt += chr(padding) * padding

    encoder = DES.new(result[:8], DES.MODE_CBC, result[8:16])
    encrypted = encoder.encrypt(plaintext_to_encrypt)

    print encrypted.encode('base64')

我现在正在尝试执行相反的操作(解密)并知道 _password _salt _iterations 变量,当然。

print encoder.decrypt(encrypted)与初始密码不匹配。

我不知道接下来该做什么。我阅读rfc2898的§6.1.2,但它对我没有帮助。谁能引导我找到正确答案?

编辑:
似乎需要以下内容:

encoder2 = DES.new(result[:8], DES.MODE_CBC, result[8:16])
print encoder2.decrypt(encrypted)

为什么我必须再次使用DES.new()?如何摆脱填充?
“123456”的实际解密输出为123456☻☻

2 个答案:

答案 0 :(得分:1)

这样做

    decrypted = encoder2.decrypt(encrypted)
    print decrypted.rstrip('\2,\1,\3,\4,\5,\6,\7')

“123456”的长度为6,解密器输出8个字节。剩下的位置用一个默认字节填充,因此rstrip剥离字节并给出字符串。

编辑:我已经创建了一个要点,请参阅此内容 Link

答案 1 :(得分:0)

只取最后一个字节并删除它编码的字符数(包括最后一个字节)。

请注意,如果您容易受到填充oracles等错误的影响,则应添加身份验证标记。