pihug12
pihug12

Reputation: 317

Python 2 - Decrypt Java's PBEWithMD5AndDES

This question is related to this one: Replicate Java's PBEWithMD5AndDES in Python 2.7


This was the answer of the question (Python code):
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')

I'm now trying to do the reverse operation (decrypt) with knowing the _password, _salt and _iterations variables, of course.

print encoder.decrypt(encrypted) doesn't match the initial password.

I don't know what to do next. I read the §6.1.2 of the rfc2898 but it didn't help me. Can anyone guide me to the right answer?

EDIT :
Seems like the following is needed:

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

Why do I have to use DES.new() again? How can I get rid of the padding?
Actual decrypted output for "123456" is 123456☻☻

Upvotes: 4

Views: 1866

Answers (2)

Rohit
Rohit

Reputation: 122

Do like this

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

Length of "123456" is 6 and the decrypter outputs 8 bytes. The remaining position is filled with a default byte, so the rstrip strips the bytes and gives the string.

EDIT: I have created a gist refer this Link

Upvotes: 1

Maarten Bodewes
Maarten Bodewes

Reputation: 93968

Just take the last byte and remove as many characters as it encodes (including the last byte).

Beware that you should add an authentication tag if you are vulnerable to error oracles such as padding oracles.

Upvotes: 0

Related Questions