8

I've got a generated MD5-hash, which I would like to compare to another MD5-hash from a string. The statement below is false, even though they look the same when you print them and should be true.

hashlib.md5("foo").hexdigest() == "acbd18db4cc2f85cedef654fccc4a4d8"

Google told me that I should encode the result from hexdigest(), since it doesn't return a string. However, the code below doesn't seem to work either.

hashlib.md5("foo").hexdigest().encode("utf-8") == "foo".encode("utf-8")
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
nip3o
  • 3,346
  • 4
  • 24
  • 29

3 Answers3

15

Python 2.7, .hexdigest() does return a str

>>> hashlib.md5("foo").hexdigest() == "acbd18db4cc2f85cedef654fccc4a4d8"
True
>>> type(hashlib.md5("foo").hexdigest())
<type 'str'>

Python 3.1

.md5() doesn't take a unicode (which "foo" is), so that needs to be encoded to a byte stream.

>>> hashlib.md5("foo").hexdigest()
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    hashlib.md5("foo").hexdigest()
TypeError: Unicode-objects must be encoded before hashing

>>> hashlib.md5("foo".encode("utf8")).hexdigest()
'acbd18db4cc2f85cedef654fccc4a4d8'

>>> hashlib.md5("foo".encode("utf8")).hexdigest() == 'acbd18db4cc2f85cedef654fccc4a4d8'
True
pycruft
  • 66,157
  • 1
  • 20
  • 12
  • Your last piece of code worked fine. Somehow, I got no error-message when testing on my AppEngine development server. I should've tested it in the python console instead. I apologize and will do that next time. – nip3o Aug 27 '10 at 11:49
5

Using == for a hash comparison is likely a security vulnerability.

https://groups.google.com/forum/?fromgroups=#!topic/keyczar-discuss/VXHsoJSLKhM

It's possible for an attacker to look for timing differences and iterate through the keyspace efficiently and find a value that will pass the equality test.

jwilkins
  • 401
  • 5
  • 4
  • 2
    Python 3.3 adds a function for secure hash comparison: http://docs.python.org/3/library/hmac#hmac.compare_digest – merwok Jan 31 '13 at 17:13
2

hexdigest returns a string. Your first statement returns True in python-2.x.

In python-3.x you would need to encode argument to md5 function, in that case equality is also True. Without encoding it raises TypeError.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293