• 隐藏侧边栏
  • 展开分类目录
  • 关注微信公众号
  • 我的GitHub
  • QQ:1753970025
Chen Jiehua

用户密码存储 

目录

原文:http://zhuoqiang.me/password-storage-and-python-example.html

可还原明文

密码明文直接存储在系统中

这种方法下密码的安全性比系统本身还低,管理员能查看所有用户的密码明文。除非是做恶意网站故意套取用户密码,否则不要用这种方式

密码明文经过转换后再存储

与直接存储明文的方式没有本质区别,任何知道或破解出转换方法的人都可以逆转换得到密码明文

密码经过对称加密后再存储

密码明文的安全性等同于加密密钥本身的安全性。对称加密的密钥可同时用于加密与解密。一般它会直接出现在加密代码中,破解的可能性相当大。而且系统管理员很可能知道密钥,进而算出密码原文

密码经过非对称加密后再存储

密码的安全性等同于私钥的安全性。密码明文经过公钥加密。要还原密码明文,必须要相应的私钥才行。因此只要保证私钥的安全,密码明文就安全。私钥可以由某个受信任的人或机构来掌管,身份验证只需要用公钥就可以了

实际上,这也是 HTTPS/SSL 的理论基础。这里的关键是 私钥的安全 ,如果私钥泄露,那密码明文就危险了。

 

不可还原明文

通常利用哈希算法的单向性来保证明文以 不可还原的有损方式 进行存储。

使用自己独创的哈希算法对密码进行哈希,存储哈希过的值

哈希算法复杂,独创对理论要求很高。一般独创的哈希算法肯定没有公开经过时间检验的算法质量高,天才另算

使用 MD5 或 SHA-1 哈希算法

MD5 和 SHA-1 已破解。虽不能还原明文,但很容易找到能生成相同哈希值的替代明文。而且这两个算法速度较快,暴力破解相对省时,建议不要使用它们。

使用更安全的 SHA-256 等成熟算法

更加复杂的算法增加了暴力破解的难度。但如果遇到简单密码,用彩虹字典的暴力破解法,很快就能得到密码原文

加入随机 salt 的哈希算法

密码原文(或经过 hash 后的值)和随机生成的 salt 字符串混淆,然后再进行 hash,最后把 hash 值和 salt 值一起存储。验证密码的时候只要用 salt 再与密码原文做一次相同步骤的运算,比较结果与存储的 hash 值就可以了。这样一来哪怕是简单的密码,在进过 salt 混淆后产生的也是很不常见的字符串,根本不会出现在彩虹字典中。salt 越长暴力破解的难度越大

具体的 hash 过程也可以进行若干次叠代,虽然 hash 叠代会增加碰撞率,但也增加暴力破解的资源消耗。就算真被破解了,黑客掌握的也只是这个随机 salt 混淆过的密码,用户原始密码依然安全,不用担心其它使用相同密码的应用。

Python 示例:如何使用 salt 加 hash 来单向转换密码明文


import os
from hashlib import sha256
from hmac import HMAC

def encrypt_password(password, salt=None):
    """Hash password on the fly."""
    if salt is None:
        salt = os.urandom(8) # 64 bits.

    assert 8 == len(salt)
    assert isinstance(salt, str)

    if isinstance(password, unicode):
        password = password.encode('UTF-8')

    assert isinstance(password, str)

    result = password
    for i in xrange(10):
        result = HMAC(result, salt, sha256).digest()

    return salt + result

验证:

def validate_password(hashed, input_password):
    return hashed == encrypt_password(input_password, salt=hashed[:8])

assert validate_password(hashed, 'secret password')

 

总结

上善不战而屈人之兵。如果可能不要存任何密码信息 让别人(OpenID)来帮你做事,避开这个问题

如果非要自己认证,也只能存 不可逆的有损密码信息 。通过单向 hash 和 salt 来保证只有用户知道密码明文,绝对不能存可还原密码原文的信息 。

如果因为种种原因一定要可还原密码原文,请使用非对称加密,并保管好私钥。

码字很辛苦,转载请注明来自ChenJiehua《用户密码存储》

评论