Is it possible to add a salt to passwords in .hpasswd files? I assume not since the server would need the开发者_开发百科 salt for each user in order to verify the password and I can't think of how it would get them, but otherwise if the list was to be obtained it would be rather vulnerable. Is there a solution?
Many thanks for your help, Ben
By default htpasswd uses the standard crypt function and thus passwords are already salted - note in this example that both users have the same password yet the hashes are different:
simon@diablo:~$ htpasswd -b -c htpasswd simon abcd Adding password for user simon simon@diablo:~$ htpasswd -b htpasswd simon2 abcd Adding password for user simon2 simon@diablo:~$ cat htpasswd simon:NWvm/LCCxQ64E simon2:2I.LBzsRqULN6
(note: the -b
flag is normally discouraged because other users can see your command line arguments and hence the password)
The first two characters of the hash are the salt; passwords are verified by calling crypt()
again. Entering the wrong password produces a string that's unequal to the hashed password:
>>> from crypt import crypt
>>> crypt("wrongpass", "NWvm/LCCxQ64E")
'NWbxQgX1unvso'
whereas the correct password produces the expected hash:
>>> crypt("abcd", "NWvm/LCCxQ64E")
'NWvm/LCCxQ64E'
htpasswd -m
uses a different algorithm that's MD5-based and uses a longer salt:
simon@diablo:~$ htpasswd -m -b -c htpasswd simon abcd Adding password for user simon simon@diablo:~$ cat htpasswd simon:$apr1$mfvnBVmG$iIHIHOaH9vcImG5G.8eVa/
Here, the salt is the 8 characters between the second and third $
.
htpasswd -s
stores a SHA-1 digest with no salt; this appears to be for compatibility with Netscape/LDIF:
simon@diablo:~$ htpasswd -s -b -c htpasswd simon abcd Adding password for user simon simon@diablo:~$ htpasswd -s -b htpasswd simon2 abcd Adding password for user simon2 simon@diablo:~$ cat htpasswd simon:{SHA}gf6L/odXbD7LIkJvjleEc4KRes8= simon2:{SHA}gf6L/odXbD7LIkJvjleEc4KRes8=
These can easily be reversed - convert into a hex digest:
>>> "".join("%02x" % ord(c)
... for c in "gf6L/odXbD7LIkJvjleEc4KRes8=".decode("base64"))
'81fe8bfe87576c3ecb22426f8e57847382917acf'
then use an online hash database.
The htpasswd
utility already does use salts in most cases:
The crypt() and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult.
And that's (sort of) the purpose of salts in password files. While salts have to be included in the server's .htpasswd
file for the server to be able to check passwords, it is the numerous different possibilities of what a salt could be that defends against such attack techniques as rainbow tables.
However, if your users pick weak or common passwords, password cracking is a problem anyways, since the attacker (presumed to have access to the password file) will try those first, very quickly in fact (not limited by the speed of the server and Internet connection), by guessing in the normal way. The best advice I can give is that users should always pick strong passwords.
精彩评论