Password authentication systems

Paul Rubin http
Thu Aug 10 10:12:43 EDT 2006


neokosmos at gmail.com writes:
> Presumably, this is done using the crypt() system call (and,
> fortunuately, Python has a builtin crypt module!).  Presumably, as
> well, this is at least somewhat secure, assuming a source of
> cryptographic randomness to use to choose the salt.  Are SHA1 and MD5
> suitable for this sort of thing as well, or would I need to move to
> something more "industrial strength" from, say, the pyCrypto module if
> I wanted to avoid a dependency on the crypt module?

The salt doesn't really have to be cryptographically random.
There are two main issues:

1) Unix password hashing uses several different algorithms depending
on version and configuration.  Do you need to interoperate, or are you
just trying to do something similar?

2) Even with salting, computers are fast enough thse days to run
dictionary searches against unkeyed hashed passwords, so Unix now uses
a non-publicly-readable shadow password file.  You're best off hashing
with an actual secret key, if you have a way to maintain one.  I'd
suggest using the hmac module:

   hash = hmac.new(secret_key, password).hexdigest()

will give you a hex digit string; or if you prefer, you could use
.digest() instead of .hexdigest() and base64 encode it if you want
printable output.  Keep in mind, though, that if the secret key leaks,
you effectively have an unsalted hash.  You could add a salt if
you want (untested):

   import os
   salt = os.urandom(8)  # 8 random bytes
   hash = (salt, hmac.new(secret_key, salt + password).digest())

note that the salt and hash are both binary.  You may want to encode
them (e.g. base64) if you need printable chars.



More information about the Python-list mailing list