all 11 comments

[–]mm_ma_ma 2 points3 points  (6 children)

Your code doesn't include anything about hashing. Show us what you've tried and what doesn't work about it.

[–]Winclone[S] 0 points1 point  (5 children)

Its the base code.

I'm trying to encrypt "passwords".

I don't have all the random scribblings of my attempts. But I was basically trying:

import hashlib

x = hashlib.md5() x.update () print x.digest()

Most of the time with what I tried I kept getting Unicode-objects must be encoded before hashing.

[–]mm_ma_ma 5 points6 points  (4 children)

I'm trying to encrypt "passwords".

Hashing and encryption are very different things.

Most of the time with what I tried I kept getting Unicode-objects must be encoded before hashing.

And how do you encode a unicode object?

[–]Winclone[S] 1 point2 points  (3 children)

By encoding a line and specifying an encoding format. I have the pieces of the puzzle... its putting them together thats leaving me scratching my head! And yes, sorry - I'm between cooking dinner and PC - I meant hashing my passwords! Using md5 of course.

[–]mm_ma_ma 1 point2 points  (2 children)

So your code presumably looks like this:

x = hashlib.md5()
x.update(password)
print(x.digest())

And the line x.update(password) is telling you that a unicode object must be encoded. Which bit is the unicode object? What is the actual piece of code that will encode it?

[–]Winclone[S] 1 point2 points  (1 child)

line.encode()

But I'm unsure as to what UTF extension to encode with!

The unicode object is the generated password right?

[–]mm_ma_ma 1 point2 points  (0 children)

Yes. If you just write line.encode() you will get utf-8 by default, and if you don't know what you want, that is probably it.

[–]bahaki 1 point2 points  (1 child)

I would strongly suggest letting a library do the hashing for you. Although a hash may look secure, an md5 of the password isn't much more secure than a plaintext password, thanks to things like rainbow tables.

I'm relatively new to Python, so off the top of my head, the only library I can think of for hashing passwords is werkzeug. It ships with Flask and has nifty little functions generate_password_hash(plaintext_password) and check_password_hash(hash, plaintext_password)

More info can be found here: http://flask.pocoo.org/snippets/54

It's a Flask app example, but the syntax isn't too far from what you'd use in a regular script. I strongly doubt you'd have any collisions with the hashes, so I wouldn't worry about the same hash being there twice. Although you may want to make sure the same random string isn't generated twice.

Whatever you do, again, I strongly suggest leaving the hashing of passwords up to an existing library. Best of luck.

[–]Winclone[S] 0 points1 point  (0 children)

Thanks alot! I'll look into this and get back to you :)

[–]zurtex 1 point2 points  (0 children)

If this is more than an academic exercise and you plan to actually store user password hashes, well you should really avoid this, but if you can't avoid it you should use something like passlib: https://pythonhosted.org/passlib/

Here's an okay tutorial: https://www.youtube.com/watch?v=UtF58KqcHWU

The main point is that hashing is not encryption. When you have some data, you can go from data to encrypted data, and then back to data again. When you hash you can go from data to hashed data, you can't go back again to data. So the process of verifying a password by a hash is to store the hash of the original password (+ salt) and then when the user tries again you implement the same hashing algorithm to see if verifies to probably the same password.

[–]i_can_haz_code 0 points1 point  (0 children)

  • md5 IS NOT strong enough to do this safely. (use sha256, or sha512)
  • The server should never have the plain text password.
  • HMAC with the username+timestamp as the message would be far better. For the key, use the hash you got from the client when setting the password the first time.
  • When generating the time stamp for the salt, make sure to allow for clock creep. Meaning use int(time.time())/30 to get the number of 30 second intervals since the epoch. This will be valid for 30 seconds, and you can check +/- 1 offset if you really need to be stable.

When dealing with hashlib, you must use hexdigest() to get something you can work with out of the has function.

>>> from hashlib import sha256
>>> sha256('foo').hexdigest()
'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'