使用密码中的随机数字进行身份验证

时间:2014-01-27 17:47:52

标签: c# java authentication encryption passwords

这个问题更多的是设计知道而不是纯粹的技术问题。

我想知道实现身份验证机制的最佳方法是什么,要求用户在整个密码中输入/选择特定位置的字符。恩。要求用户输入/选择第3,第5和第9个字符,然后检查他们是否从原始密码输入/选择了正确的字符。

据我所知,在存储密码之前,使用不可逆算法对密码进行加密和加密。当用户输入他的整个密码时,它再次被盐化,加密并与存储的值进行比较。但在上述只输入/选择某些字符的情况下,如何检查整个密码?

以下是我实现上述

的两种(不安全)方式
  • 将原始密码分解为单个字符然后 腌制和加密它们。然后比较用户输入的值 反对特定的角色。
  • 将原始密码分解为预定义的一组组合,例如2nd,3rd&第7个字符,然后盐渍和 加密他们。稍后与用户输入的值进行比较。

但我认为通过上述实现,很容易破解密码而不是破解整体加密的密码。

实施此方法最安全的方法是什么?


更新: 刚刚发现此主题已经详细讨论here,并提到了使用HSM和对称加密。

3 个答案:

答案 0 :(得分:3)

将密码分解为黑客可以独立攻击的不同部分,可显着降低密码的整体复杂性。基本上你允许黑客用密码播放“20个问题”:“单独的数字是500吗?不,750怎么样?”

此外,绝大多数典型的应用用户都会觉得这项任务既困难又具挑战性。

我不建议这样做。

您是正确的,通常会存储盐渍的哈希(未加密)密码。如果您正在进行散列而不是加密,则需要一些机制来分别知道密码的这些特定数字是什么。你应该进行盐腌/散列。一些备受瞩目的网站因为使用加密而导致许多用户帐户遭到入侵,并且黑客发现了加密密钥。

答案 1 :(得分:0)

这样做可以降低密码给你的熵。以8个字符的密码为例。现在我们假设您的密码是随机选择的,我们只是尝试通过尝试每种组合来强制它。这个公式是(n + r-1!)/ r!(n-1)!意思是8个字符(r = 8)(大写和小写以及数字n =(26 * 2 + 10))所有组合都会出现 8361453670 不同的组合。

现在让我们说,你要求他们给你第1,第3和第6个字符你已经有效地减少了选择(r)到3的数字,因为为了强制每个组合我只需要3个字符。您现在拥有的组合总数 41664 ,这很容易破解。事实上,这将花费时间。

你永远不应该减少你的熵,事实上我建议用字母数字和符号创建至少10个字符的密码。

关于“不可逆加密”的问题,你指的是哈希。密码应该存储散列和盐渍,实际上它们应该使用缓慢的散列,如BCrypt,SCrypt或PBKDF2。但是为了能够做你所说的,你将被要求用可逆加密来加密密码。这是禁忌,因为密钥可能会被盗,在这种情况下,您的密码也可能是纯文本。

存储密码的最佳方法是不存储密码(如果可以,则使用open id或其他内容,这样您就不必承担责任)。存储密码的第二种最佳方法是将它们存储起来,就好像你要松开它们一样。 Salted + Hashed具有非常慢的算法,可以给您足够的时间来警告您的用户并给他们足够的时间来更改他们的密码。

答案 2 :(得分:-2)

密码通常以加密格式存储。它用特定的盐加密。 salt告诉加密算法一些初始化向量。这种加密是一种方式。没有办法解密它。

这样就很难建立一个彩虹密码表,因为你需要对每个盐组合都这样做。请参阅以下WIKI ..​​ http://en.wikipedia.org/wiki/Rainbow_table

您提出的方法会严重降低您从良好密码中获得的安全性。