有个工程师在提问,如果我把密码hash后存储在数据库,是不是就安全了[1]。
linux上用户密码以hash形式存储,用户输入密码,计算其hash值,然后和存储的比较,如果相同,则密码正确。
这是hash的看家本领,hash值我可以公开给你看,但是你不能反算出密码。只有用户自己知道密码。
hash虽然是不可逆的,但是现在计算机太快了,可以进行暴力破解,在普通的桌面系统上,都可以达到千万次每秒。
$ openssl speed md5 sha256
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
md5 171098.19k 388232.38k 675897.60k 835082.27k 893714.43k 897231.53k
sha256 105633.24k 232554.86k 431141.89k 537461.42k 569461.42k 578633.73
简单hash的一个重大问题是:offline dictionary attack。而导致这个问题的根源是服务器不安全。如果服务器是绝对安全的
,我相信使用md5来hash密码也是安全的。
如果黑客黑进服务器,拿到所有用户数据的一个拷贝。那么就存在以下问题,黑客不需要破解所有的密码,能破解一个密码,比如是银行账户,
那么这个账户可能就有几百万元,只要一个账户,黑客就赚了,黑客可以将盗取的哈希值去事先计算好的密码-哈希数据库表去比对,
比到相同的,那就破解了一个密码。对于大多数用户而言,密码都是可能是常见的密码。
对于本地明盘的密码hash值,那就更容易暴力破解了,比如老的linux系统上,用户密码的hash值是直接存在/etc/passwd文件的。
这个文件所有用户可读。新的linux系统将hash值存储到了/etc/shadow,只有root用户可以看到。
解决办法就是:
salt和更长的hash位数。
hash(salt + passwd)
对于服务器而言,salt我可以存储在代码中,黑客不容易拿到,这样即使黑客拿到数据库,也不好进行查词典的方式进行比对破解。
对于本地明盘的而言,salt可以比较长。也极大的增加了暴力的难度。
在linux用户中,每个用户的salt都不一样,而且是明文存储到/etc/shadow的。这样的好处是,不同用户的salt不同,为这个用户建了
词典,另外一个用户就不能用。因此每个用户都需要单独暴力破解。
总结:
如果hash没有人能看到,那么使用md5也是安全的,因为去服务器验证的速率肯定是不快的,也可以加限制。那么暴力破解的几率很低。
如果hash值获取到,就要避免暴力破解和查词典。
参考:
[1] https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords
[2] https://security.stackexchange.com/questions/19906/is-md5-considered-insecure
[5] https://security.blogoverflow.com/2011/11/why-passwords-should-be-hashed/
[6] https://www.baeldung.com/linux/hashing-methods-password