I am looking to generate passwords using strings typed by the user, the book I am reading recommends using
md5 because it is considered stronger.
sha however has been deprecated and I am now using the
hashlib module to encrypt me strings in a similar way to that shown here: http://docs.python.org/py3k/library/hashlib.html#module-hashlib.
from getpass import getpass
print('Username: ' + os.environ['USER'])
passwd = getpass('Password: ')
h = hashlib.md5()
passwd_encrypt = h.hexdigest()
I am then comparing
passwd_encrypt with a plain ascii file containing a list of usernames and encrypted passwords like so:
Is this a suitable technique for encryption of the password or is there a better way? I am also interested in whether storing the passwords in this way is suitable and what the alternatives may be.
There is no "sha" algorithm. The sha1 algorithm is much stronger than md5, since md5 is completely broken. I believe there is an algorithm that takes microseconds to generate a collision.
Sha1 has been considerably weakened by cryptanalysts, and the search is on for the next big thing, but it is still currently suitable for all but the most paranoid.
With regard to their use in passwords, the purpose is to prevent discovery of the original password. So it doesn't really matter much that md5 collisions are trivial to generate, since a collision simply yields an alternate password that has the same md5 hash as the original password, it doesn't reveal the original password.
Your version is missing an important component: the salt. This is a random string that is concatenated to the original password in order to generate the hash, and then concatenated to the hash itself for storage. The purpose is to ensure that users with the same password don't end up with the same stored hash.
import random print('Username: ' + os.environ['USER']) passwd = getpass('Password: ') salt = ''.join(random.choice('BCDFGHJKLMNPQRSTVWXYZ') for range(4)) h = hashlib.md5() h.update(salt) h.update(passwd.encode()) passwd_encrypt = salt + h.hexdigest()
You then verify the password by reusing the stored salt:
passwd = getpass('Password: ') salt = passwd_encrypt[:4] h = hashlib.md5() h.update(salt) h.update(passwd.encode()) if passwd_encrypt != salt + h.hexdigest(): raise LoginFailed()
Comparing the hash of the password with a saved hash is a suitable method for authentication.