📜  如何在数据库中存储密码?

📅  最后修改于: 2021-04-16 06:12:10             🧑  作者: Mango

大多数Web应用程序要求其用户通过询问用户名和密码来对自己进行身份验证。他们将用户提供的凭据与存储在其数据库中的数据进行比较,如果凭据匹配,则授予用户访问权限。听起来不错!但是,如果网站存储密码的数据库遭到破坏,将会发生什么?
本文介绍了在数据库中存储密码的各种技术。

根据裸露的安全性,大多数网站中有55%的网络用户使用相同的密码!这意味着,如果以纯文本形式存储您的密码的网站遭到破坏,黑客不仅可以访问该网站上的帐户,还可以访问您使用相同密码的所有社交媒体,电子邮件,论坛等帐户!好吧,许多人一定想知道,如果数据库暴露给黑客,那该怎么办?黑客有权访问所有信息。错误的!!对于黑客来说,有许多方法可以使从数据库中检索密码的过程变得繁琐。即便如此,开发人员还是倾向于忽略基本准则,而是以纯文本形式存储密码。有超过30%的网站以纯文本形式存储您的密码(还包括一些知名网站)。如果网站以纯文本形式存储您的密码,那么无论您选择多强的密码,都不安全!
在数据库中存储纯文本密码是一种罪过。
可能还会有人认为,如果不是纯文本格式,那么我们必须对密码进行加密,然后再进行存储。这也是一个可怕的想法。加密功能提供输入和输出之间的一对一映射,并且它们始终是可逆的。如果黑客获得了密钥,他将能够解密密码。更好的方法是使用单向加密哈希函数。哈希函数在输入和输出之间提供多对一映射,实际上不可能反转输出。好的加密哈希函数具有较少的冲突(即,对于函数的不同输入值,很难获得相同的输出)。由于鸽洞原理,无法完全避免碰撞。对于哈希密码,我们可以假设哈希函数将生成唯一的输出,即对于没有两个不同的密码,我们将获得相同的哈希值。一些流行的加密哈希函数是MD5和SHA1。代替将纯文本密码存储在数据库中,一种方法是存储密码的哈希。您可能会想,如果我们无法从哈希中获取实际的密码,那么我们将如何验证用户输入的凭据?很简单,对用户输入的密码应用相同的哈希函数,然后将其与数据库中存储的哈希进行比较。如果两个哈希都匹配,则对用户进行身份验证(因为相同输入的哈希将提供相同的输出)。现在,如果攻击者能够访问数据库,则他将只能查看哈希输出,而不能查看实际密码。使用加密哈希函数比存储纯文本密码更好黑客是聪明人,一旦他们知道开发人员正在存储哈希密码,便会预先计算大量单词(从常用单词列表或词典单词中)的哈希值。他们创建了一个单词表及其相应的哈希表。该表称为彩虹表,可随时在线获得。他们可以使用此表通过比较从数据库获得的哈希值来反向查找实际密码。因此,拥有一个强大的密码非常重要,因为密码出现在单词列表中的可能性越来越小。

密码彩虹表

简单地存储密码的哈希值将无济于事。随着GPU和CUDA,OpenCL库的引入,处理能力大大提高。快速的GPU可以在一秒钟内生成数百万个MD5 / SHA1哈希。因此,黑客可以通过暴力破解各种可能的组合轻松地生成大量哈希,并将其与数据库中存储的哈希进行比较以提取实际密码。

甚至哈希密码也不安全!感到惊讶吗?
不要失去希望!开发人员仍然可以采取一些措施来防止您的密码被黑客窃取。加入一些盐使密码更美味!是的,对..!加盐。盐是随机数据,在将其作为哈希函数的输入发送之前,已与您的密码连接在一起。例如
如果您的密码是abc ,并且盐是!ZaP0#8 ,则hashFunction(’abc!ZaP0#8’)的结果将存储在数据库中,而不是hashFunction(’abc’)
因此,彩虹表攻击现在将不再有效,因为彩虹表包含“ abc!ZaP0#8”散列的可能性很小(因为通常彩虹表是由常用词,字典词等构成的)。 Salt不存储在数据库中,而仅存在于外部用户无法访问的应用程序配置文件中。获得对源文件的访问比获得对数据库的访问要困难。上述加盐方法是静态的。我们为所有密码设置了一个固定的位数。要验证用户身份,请先将固定盐连接到用户提供的输入(密码),然后将值传递给哈希函数,然后将其与数据库中存储的值进行比较。但是,这种方法仍然容易受到暴力攻击,如果攻击者能够获得静态盐,他可以通过将盐串联在每个单词中来使用旧的攻击方法。更好的方法是使用动态盐。对于每个用户,加密强度高的随机字符串生成器都会生成新的盐。用户输入的密码与随机生成的盐和静态盐串联在一起。连接的字符串作为哈希函数的输入传递。获得的结果存储在数据库中。动态盐需要存储在数据库中,因为动态盐对于不同的用户而言是不同的。当要对用户进行身份验证时,首先从数据库中获取该用户的动态盐的值,然后将其与用户提供的输入和静态盐连接起来。将结果与存储在数据库中的哈希进行比较。如果数据库遭到破坏,黑客不仅会获取您的密码哈希,还会获取所使用的动态盐。您可能想知道,如果攻击者拥有动态盐,那么动态盐相对于静态盐的优势是什么?即使攻击者拥有动态盐,他也需要为数据库中存在的每个用户(根据动态盐)创建一个新的哈希表(或Rainbow表)。这比为所有用户只创建一张表要昂贵得多。上面的方法对于降低黑客的速度非常有用。但是,建议使用bcryptscrypt之类的算法代替MD5 / SHA1。 Bcrypt是基于Blowfish的哈希算法。它要求您指定成本/工作系数。工作因子使整个过程变慢,因此生成哈希表所花费的时间将增加多次。参考 :
https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/