Python MD4 function could not generate hash code as in the online MD4 hash generator

yoonghm :

MD4 hash code generated from Python are different from the online. I know it must be due to encoding. Can you help?

from Crypto.Hash import MD4

psk = 'The quick brown fox jumps over the lazy dog'

h = MD4.new()
h.update(psk.encode('UTF-16LE'))
print(f'UTF-16LE: {h.hexdigest()}')

h.update(psk.encode('UTF-16'))
print(f'UTF-16:   {h.hexdigest()}')

h.update(psk.encode('UTF-8'))
print(f'UTF8:     {h.hexdigest()}')

h.update(psk)
print(f'UTF8?:    {h.hexdigest()}')

The hash outputs for 'The quick brown fox jumps over the lazy dog' in different encoding are:

UTF-16LE: 4e6a076ae1b04a815fa6332f69e2e231
UTF-16:   db8ae265b09c6ffa1e2fc163d66f64a4
UTF8:     324563ee68cc8009c82778d70d958723
UTF8?:    1aaf934b705b1d2aab69b0cf2a9cd87b

The online MD4 hash function (https://emn178.github.io/online-tools/md4.html) would give

1bee69a46ba811185c194762abaeae90

Update:

Thank you for comment, I have updated the code:


import getpass
from Crypto.Hash import MD4

psk = 'The quick brown fox jumps over the lazy dog' #getpass.getpass()

h = MD4.new(data=psk.encode('UTF-16LE'))
print(f'UTF-16LE: {h.hexdigest()}')

h = MD4.new(data=psk.encode('UTF-16'))
print(f'UTF-16:   {h.hexdigest()}')

h = MD4.new(data=psk.encode('UTF-8'))
print(f'UTF8:     {h.hexdigest()}')

h = MD4.new(data=psk)
print(f'UTF8?:    {h.hexdigest()}')

The new output is

UTF-16LE: 4e6a076ae1b04a815fa6332f69e2e231
UTF-16:   c6274a58a30e434503b45d2ce95e6c19
UTF8:     1bee69a46ba811185c194762abaeae90
UTF8?:    1bee69a46ba811185c194762abaeae90

I also discovered that https://emn178.github.io/online-tools/md4.html use UTF-16 even though I passed it a file with UTF-16LE encoding.

WPA2 Enterprise requires text to be encoded in UTF-16LE.

bechtold :

With update you obviously update the hash, meaning you feed in more pieces of your message. So you are actually feeding in the string multiple times with different encodings which in the end gives a hash for more than just your string.

If you only update once you'll get the expected result.

from Crypto.Hash import MD4

psk = 'The quick brown fox jumps over the lazy dog'

h = MD4.new()

h.update(psk.encode('UTF-8'))
print(f'UTF8:     {h.hexdigest()}')

From the documentation of digest, from which the hexdigest method is a derivative:

Return the digest of the strings passed to the update() method so far. This is a string of digest_size bytes which may contain non-ASCII characters, including null bytes.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=291146&siteId=1