加密密码

时间:2010-01-26 14:45:17

标签: c# encryption

我已经阅读了一些问题,这些问题建议散列密码并将其存储在数据库中。

当有人登录时,您将使用存储的密码散列密码。

我不明白这是怎么回事?两个字符串可以散列到相同的值 - 不太可能但确实可能

有人能帮助我吗?

编辑:任何人都可以提供碰撞可能性的统计数据吗?

17 个答案:

答案 0 :(得分:24)

您不应该存储未加密的密码,因为您的数据库管理员不应该有权访问客户密码。

散列密码可防止数据库管理员看到密码。

碰撞的可能性非常小并不是问题,因为在锁定账户之前,这并没有显着增加某人试图强行获取客户密码的机会。

PS在散列之前加密密码也是一种好习惯,如果黑客以某种方式访问​​密码表,那么仍然难以蛮力。使用彩虹表等更难。

答案 1 :(得分:10)

  

两个字符串可以散列为相同的值    - 不太可能,但确实可能

是的,但如果哈希足够大并且质量很好,那么不用担心就不够了。在口语方面:应用程序的每个用户同时被闪电击中都不是很好,但绝对可能。你担心吗?

答案 2 :(得分:5)

即使两个字符串可以散列到相同的值(并且它们肯定会这样做,因为可能值的空间比散列的空间大得多),找到这样的字符串对仍然不是那么容易(假设你使用强哈希函数)。

因此,如果攻击者想要在不知道密码的情况下以其他人的身份登录,他就必须找到一个密码,该密码具有相同的哈希值,这个密码应该与查找密码一样困难(哈希函数的不可逆性是基本财产)。

如果要在.NET中使用散列,请尝试类似

的内容
    public static string ComputeHash(string plaintext)
    {
        HashAlgorithm mhash = new SHA1CryptoServiceProvider();
        byte[] bytValue = Encoding.UTF8.GetBytes(plaintext);
        byte[] bytHash = mhash.ComputeHash(bytValue);
        mhash.Clear();
        return Convert.ToBase64String(bytHash);
    }

答案 3 :(得分:4)

您所指的是“碰撞漏洞”。但首先是一点背景。

如果你存储一个未加密的密码,这是一个安全漏洞,你可能已经猜到了,Sam建议。但是,您可以使用经过验证的算法,从而降低这种可能性。你绝对不应该尝试发明自己的(因为你似乎不是算法开发人员)。

我通常使用MD5,它可以在mysql等数据库中使用。这样,您也可以将检查嵌入数据库查询中。

现在,不幸的是MD5并不具备碰撞能力。然而,碰撞的可能性非常小。您可以查看留言板上的其他建议。我知道SHA-2就是这样一种可能性。我不知道在应用程序中使用它有多容易。

答案 4 :(得分:3)

“MyAwesomePassword1”和“@ @#ngt0n8 $ !! ~~~ 09 || {2` =& - [kla2%!B q”)可以哈希相同值不是安全漏洞。

答案 5 :(得分:2)

你可以说“绝对可能”,因为它是可以证明的,但是使用一个好的哈希算法,这是非常不可能的。有很多关于选择散列算法的文章,碰撞率是选择过程中的一个重要因素。

人们提倡哈希与加密的原因是因为哈希是一种单向操作。从用户安全的角度来看,碰撞的可能性使得散列成为一个很好的选择。因为两个值可以产生相同的哈希值,哈希值不可逆转。这使得某人无法(或几乎不可能)破解您的数据库并获取其他站点的登录凭据(因为用户经常在系统中使用与[许多]相同的密码)其他)。

答案 6 :(得分:1)

必须开发散列函数,使得它不太可能为2个不同的输入提供相同的散列,即它是抗冲突的。有关更多信息,请访问wikipedia

答案 7 :(得分:1)

如果您担心碰撞,请使用512位的SHA-2。然后,SHA-1算法还没有得到证明的碰撞,所以它仍然足够安全,不用担心碰撞。

答案 8 :(得分:1)

是的,这是可能的,但不太可能是一个体面的哈希。

举个例子: SHA1是160位,意味着找到两个具有相同散列的字符串,你需要散列大约2 ^ 80个不同的字符串。即使使用我们所有最好的超级计算机,也没有人发现两个字符串哈希到相同的SHA1值(虽然我预测很快就会发生)。

答案 9 :(得分:1)

即使碰撞机会可能很小(“苗条”取决于您的散列算法),但这并不重要,是吗?

即使您对用户x和用户y使用相同的密码哈希,您也永远不会比较两个用户的密码,以确定它们是否基于哈希值相同!因此,虽然'技术上'是一个碰撞哈希,但在这种情况下它并没有真正碰撞/干扰/重要。

答案 10 :(得分:1)

这是一个很好的实现。

  private static string CreateSalt(int size)
  {
   //Generate a cryptographic random number.
   RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
   byte[] buff = new byte[size];
   rng.GetBytes(buff);

   // Return a Base64 string representation of the random number.
   return Convert.ToBase64String(buff);
  }

private static string CreatePasswordHash(string pwd, string salt)
  {
   string saltAndPwd = String.Concat(pwd, salt);
   string hashedPwd =
    FormsAuthentication.HashPasswordForStoringInConfigFile(
    saltAndPwd, "sha1");

   return hashedPwd;
  }

来源:http://davidhayden.com/blog/dave/archive/2004/02/16/157.aspx

答案 11 :(得分:0)

以md5哈希字符串为例 - 它有128位,这意味着可以生成2 ^ 128个不同的哈希值。即使考虑到Birthday Paradox非常不可能可以找到不是实际密码的字符串来生成哈希值(当然,md5已被发现不安全,但这是另一个问题,md5只是一个例子。)

所以说你有一个密码,程序对它进行哈希处理,并将哈希值放入数据库中。当您尝试登录时,您键入的内容将进行哈希处理并针对该哈希进行检查 - 如果是猜测,则表示您有正确的1 ^ 2 ^ 128。这是无限小的,实际上以这种方式破解密码(蛮力)是“不可行的”。增加位数,除非哈希算法至少部分地进行逆向工程,否则实际上变得不可能。

答案 12 :(得分:0)

使用适当的哈希算法,碰撞的可能性非常小。只要你能够一致地计算哈希值,那么两个字符串是否恰好具有相同的哈希值并不重要(只要它不经常发生)。您只是将用户输入的密码的哈希值与您存储在数据库中的哈希值进行比较。

答案 13 :(得分:0)

如果你使用带有合适种子的SHA-512,那么这种情况发生的可能性很小(但并非不可能)。

Bruce Scheiner有一些关于各种安全技术稳健性的有趣博客 - sha1 broken

另一个考虑因素是确保具有相同密码的两个用户不会在数据库中产生相同的散列结果。

为了解决这个问题,您可以构建一个种子,其中包含特定于用户的内容,例如用户表中的用户ID键字段。

答案 14 :(得分:0)

为什么多个字符串会哈希到相同的密码值?每次用户输入他或她的密码时,它将散列到相同的值,并且将验证用户。输入几乎任何其他密码几乎肯定不会与散列值匹配。如果你使用的是一个提供64位值的好哈希函数,那么另一个密码与用户匹配的几率就是与一个密码差不多。

您要防范的是内部人员复制用户密码,并在安全性遭到破坏且密码表遭到破坏时泄露实际密码。标准技术是在密码中添加一些额外的位(盐,每个帐户应该是不同的),并使用强哈希函数。

如果你这样做,很难找到一个会产生给定哈希值的密码,除非你在密码之后尝试使用密码,直到找到正确的密码。 Hashing以这种方式提供对内部人员和入侵者的保护:访问密码表不足以以其他人的身份登录。

两个用户可能拥有相同的密码,或者(尽管这极不可能)密码会散列到相同的值。使用salt,它们在密码表中看起来不一样,所以没有入侵者或内部人员会通过查看表格知道他们的密码与其他人的密码相同。

另一个好处是许多人重复使用密码,特别是对于不需要安全的帐户。 (我的所有财务信息帐户都有不同的密码,但我在各种论坛上都使用相同的不那么强的密码。)使用salt和hash,我无法判断我在网站A上的密码是否与在网站B上,即使有两个密码表。

答案 15 :(得分:0)

散列和加密是略有不同的概念,即使md5()和sha1()和类似的本质上是执行散列的加密函数。由于理论上的散列应该为给定的输入(通常是更大的大小)提供唯一的输出,它实质上意味着每个散列都应该映射到单个输入 - 这意味着你手上有一个完美的压缩函数,可以减少大小为N的数据对于这样大小M的数据,M大于M,并且该过程是可逆的。但是,实际上会发生哈希冲突。这意味着一个哈希可能会映射到多个原始输入。这意味着单个密码哈希可能会使用不同密码的用户获取,这是一个真正的安全问题。

然而,加密保证是可逆的(当然使用正确的解密密钥),其中加密数据与原始数据具有一对一的关系。如果您的密码长度为N,则您的加密密码也是N.密码同样安全且无冲突。

正如他们所说,如果某些东西太好而不是真的,它可能是 - 如果散列可以是可逆的,总是产生原始数据,那么我们就不需要数据压缩算法 - 我们可以获取任意大小的数据,哈希吧如果需要,产生一些128位长的数据并期望它能够回收原始数据。但事实并非如此。原始数据越长,哈希越不可靠,无论其长度如何。

创建加密/解密密钥对并加密用户密码,然后将其存储在公共场所。

答案 16 :(得分:0)

确实发生了碰撞,但它们应该非常罕见,以至于不可能在一定时间内发生碰撞。

现在大多数攻击都会考虑使用的算法中的弱点,从而更快地找到要利用的冲突。 MD5已被证明比以前认为的要弱。来自The Register的article显示了如何使用弱点创建SSL证书。

更多抗性算法已被证明存在缺陷,使得更容易找到这些碰撞。

这篇PDF展示了一篇讨论SHA-1 collisons及其如何变得简单的论文。 (数学重)

出于实际目的,有人试图从哈希工具中恢复密码,例如彩虹表,

http://project-rainbowcrack.com/

这考虑到人们会选择容易的密码,因此可以使用dictionary attack(常用密码列表加上许多其他术语)来计算哈希值,并进行比较。这就是为什么始终建议使用salt