PBKDF2 加密算法

PBKDF2 是 Password-Based Key Derivation Function 的缩写,即基于密码的密钥派生算法。PBKDF2 算法就是通过加盐来生成密码的哈希值,并进行多轮的迭代计算,最终生成密钥。加盐和多轮迭代都是用来提高破解密码的难度。

我们通过使用一些哈希算法对数据进行加密。哈希算法是单向的,能够将不论什么大小的数据转化为定长的“指纹”,并且无法被反向计算。而且,即使数据源仅仅修改了一丁点,哈希的结果也会全然不同。

比如:网站登录需要输入用户名和密码,为了验证用户的身份,就需要把密码先保存到数据库,然后与用户的输入的密码进行比对。但密码属于个人敏感数据,不能保存明文,只应当保存密码的哈希值。

由于哈希算法是单向的,无法反向破解,所以很适合用于保存 password。可是,哈希加密还是能够通过字典攻击和暴力攻击破解。

我们可以通过向 password 加盐的方法避免哈希算法被破解。盐是一个加入到用户的password哈希过程中的一段随机序列。这个机制可以防止通过预先计算结果的彩虹表破解。每一个用户都有自己的盐,这种结果就是即使用户的 password 同样。通过加盐后哈希值也将不同。

所以,为了校验 password 是否正确,我们须要储存盐值。通常和password哈希值一起存放在账户数据库中。或者直接存为哈希字符串的一部分。

1. PBKDF2 算法

PBKDF2 需要以下输入:

  • 哈希算法
  • 密码
  • 盐值
  • 迭代次数

哈希算法:建议选择SHA256或更安全的算法。

密码:用户输入的密码值。

盐值:建议最少8个字节,应使用安全的随机数。

迭代次数:建议至少迭代1000次以上。

2. PBKDF2 示例

下面是Python的演示代码:

# Python 3.4+
import hashlib, binascii

def retrieve_data_from_database(user):
    """从数据库获取指定用户密码的PBKDF2哈希值,这里只是演示
    """
    data = {'yang': b'e75dfdc937acc5b7fccb2bc4237f75248c5bbe01797f70049be8abf43e55be44'}
    return data[user]

def validate_password(user, password):
    """验证密码是否正确
    password的PBKDF2哈希值和存储的PBKDF2哈希值比较,相同则验证通过
    """
    salt = b'\x7d\xef\x87\xd5\xf8\xbb\xff\xfc\x80\x91\x06\x91\xfd\xfc\xed\x69'
    dk = hashlib.pbkdf2_hmac('sha256', password, salt, 10000)
    saved_data = retrieve_data_from_database(user)
    return binascii.hexlify(dk) == saved_data

def login(user, password):
    """用户登录演示
    """
    if not validate_password(user, password):
        print('user or password error')
    # 其它逻辑

下一章:bcrypt 算法

bcrypt 是专门为密码存储而设计的密码哈希函数,基于Blowfish 加密算法变形而来,由 Niels Provos 和 David Mazières 发表于1999年的 USENIX。bcrypt函数 ...