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

📅  最后修改于: 2021-09-09 11:23:50             🧑  作者: 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 不存储在数据库中,只存在于外部世界无法访问的应用程序配置文件中。获得对源文件的访问权比获得对数据库的访问权更困难。上面的腌制方法是静态的。我们为所有密码设置了一种固定盐。要对用户进行身份验证,首先将固定盐连接到用户提供的输入(密码),然后将该值传递给散列函数并将其与存储在数据库中的值进行比较。然而,这种方法仍然容易受到暴力攻击,如果攻击者能够获得静态盐,他可以通过在每个单词中连接盐来使用旧的攻击方法。更好的方法是使用动态盐。对于每个用户,一个新的盐是由加密的强随机字符串生成器生成的。用户输入的密码与随机生成的盐和静态盐连接在一起。连接的字符串作为散列函数的输入传递。得到的结果存储在数据库中。由于不同用户的动态盐是不同的,因此需要将动态盐存储在数据库中。当要对用户进行身份验证时,首先从数据库中获取该用户的动态盐值,然后将其与用户提供的输入和静态盐连接起来。结果与存储在数据库中的散列进行比较。如果数据库遭到破坏,黑客不仅会获得您的密码哈希值,还会获得使用的动态盐。您可能想知道如果攻击者拥有动态盐,那么动态盐相对于静态盐的优势是什么?即使攻击者拥有动态盐,他也需要为数据库中的每个用户(根据动态盐)创建一个新的哈希表(或彩虹表)。这比为所有用户创建一张表要昂贵得多。上述方法可以很好地减慢黑客的速度。但是,建议使用bcryptscrypt等算法而不是 MD5/SHA1。 Bcrypt 是一种基于 Blowfish 的哈希算法。它要求您指定成本/工作因素。工作因素使整个过程变慢,因此生成哈希表所需的时间会增加数倍。参考 :
https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程