I have been looking through ths hashlib documentation but haven't found anything talking about using salt when hashing data.
Help would be great.
Samir's answer is correct but somewhat cryptic. Basically, the salt is just a randomly derived bit of data that you prefix or postfix your data with to dramatically increase the complexity of a dictionary attack on your hashed value. So given a salt s
and data d
you'd just do the following to generate a salted hash of the data:
import hashlib
hashlib.sha512( s + d ).hexdigest()
See this wikipedia article for more details
Just add the salt to your sensitive data:
>>> import hashlib
>>> m = hashlib.sha512()
>>> m.update('salt')
>>> m.update('sensitive data')
>>> m.hexdigest()
'70197a4d3a5cd29b62d4239007b1c5c3c0009d42d190308fd855fc459b107f40a03bd427cb6d87de18911f21ae9fdfc24dadb0163741559719669c7668d7d587'
>>> n = hashlib.sha512()
>>> n.update('%ssensitive data' % 'salt')
>>> n.hexdigest()
'70197a4d3a5cd29b62d4239007b1c5c3c0009d42d190308fd855fc459b107f40a03bd427cb6d87de18911f21ae9fdfc24dadb0163741559719669c7668d7d587'
>>> hashlib.sha512('salt' + 'sensitive data').hexdigest()
'70197a4d3a5cd29b62d4239007b1c5c3c0009d42d190308fd855fc459b107f40a03bd427cb6d87de18911f21ae9fdfc24dadb0163741559719669c7668d7d587'
Salting isn't a magical process that the library needs to help you with—it's just additional data provided to stop rainbow tables from working.
>>> import hashlib
>>> m = hashlib.sha512()
>>> m.update(b"Nobody inspects")
>>> m.update(b" the spammish repetition")
>>> m.digest()
b'\xd0\xf4\xc1LH\xadH7\x90^\xa7R\x0c\xc4\xafp\x0fd3\xce\t\x85\xe6\xbb\x87\xb6\xb4a|\xb9D\xab\xf8\x14\xbdS\x96M\xdb\xf5[A\xe5\x81+:\xfe\x90\x89\x0c\nM\xb7\\\xb0Cg\xe19\xfdb\xea\xb2\xe1'
>>> m.update(b"My super-secret salt.")
>>> m.digest()
b'\xcd\xd7K\xd9!~\xa8\x1d6\x9b\xa6\xde\x06\t\x02\xa1+}\xaeNA\x94a`\xaa\xf4\xe9\xb5\xff\x1f\x9cE\x84m\xbb\x98U\xb4z\x92\x9e\xe8\xc9\xc2\xc8\x8f\x068e\xb0\r\xed\xb7\xde\x80\xa6,\n\x111w{\xa2\x9b'
If you're looking for a replacement for crypt(), newer versions of glibc have SHA-512-based "$6$" with a variable iteration count (see Ulrich Drepper's page, which has a description and links to a complete C implementation of sha512_crypt_r()
).
Writing your own crypto is highly unadvisable — the above sha512(salt+password)
doesn't help against a brute-force attack.
For generating salt, use something like os.urandom(16)
for random bytes or ''.join(map(lambda x:'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[ord(x)%64], os.urandom(16)))
for random base64-alike chars (for use with crypt()-alikes).
(I say base64-alike it's not the same as the Base64 in PEM/MIME.)
use passlib, writing your own password crypto is an almost sure way to failure.
SHA512 isn't a great way to store hashed passwords these days. You should be using bcrypt or something similar. What's important is that salting is built in and that the algorithm has a significant work factor.
If you salt your SHA512 passwords by simply appending (or prepending) the salt to the plaintext, anyone who gets their hands on a set of your hashed passwords and applies a modern cracking tool (http://arstechnica.com/security/2013/05/how-crackers-make-minced-meat-out-of-your-passwords/) will be able to see the concatenated password+salt values and will probably, through trivial pattern matching, be able to separate the password portion from the salt portion for most if not all of the accounts in question.
I haven't thought this through all the way, and I am by no means a security expert, but it seems to me that if you were to encrypt (using, for example, AES256) the password using the salt as the key, and then hash that with SHA512, you'd be safe from the vulnerability I described above.
However, at that point you've put in more effort than it would have taken to switch to bcrypt and you still wouldn't have the protection of a work factor, so I would only recommend an approach like that if the environment you're working in does not offer that option.
来源:https://stackoverflow.com/questions/2898685/hashing-in-sha512-using-a-salt-python