为什么要检查错误的密码比检查正确的密码要花费更长的时间?

这个问题一直困扰着我。

在Linux上,当被要求input密码时,如果您的input是正确的,那么它立即检查,几乎没有任何延迟。 但是,另一方面,如果input错误的密码,则检查时间会更长。 这是为什么?

我在所有曾经尝试过的Linux发行版中观察到这一点。

实际上是防止每秒尝试数百万个密码的暴力攻击。 这个想法是限制密码可以检查的速度,并且应该遵循一些规则。

  • 成功的用户/密码对应该立即成功。
  • 可以检测到的失败原因应该没有明显的差别。

最后一个是特别重要的。 这意味着没有有用的消息,如:

Your user name is correct but your password is wrong, please try again 

要么:

 Sorry, password wasn't long enough 

甚至在“无效用户和密码”和“有效用户但无效密码”失败原因之间的响应时间差异。

每一次失败都应该提供完全相同的信息,文字和其他。

一些系统甚至进一步采用这种方法,在每次故障时增加延时,或者只允许三次故障,然后在允许重试之前有大的延时。

这使得猜测密码需要更长的时间。

我不确定,但是在input错误的密码之后整合一个延迟以使得攻击变得更加困难是相当常见的。 这使得一个攻击实际上是不可行的,因为它只需要很长时间来检查一些密码。

即使尝试一些密码 – 生日,猫的名字,以及类似的东西 – 也变得没有趣味。

基本上是为了减轻暴力和字典攻击。

从Linux-PAM应用程序开发者指南 :

计划延误

 extern int pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec); 

这个函数由Linux-PAM提供,以便于在调用pam_authenticate()失败之后,以及在控制返回给应用程序之前进行时间延迟。 当使用这个function时,应用程序员应该检查它是否可用,

 #ifdef PAM_FAIL_DELAY .... #endif /* PAM_FAIL_DELAY */ 

通常,应用程序通过调用pam_authenticate()或pam_chauthtok()来请求用户通过Linux-PAM进行身份validation。 这些函数调用相关Linux-PAMconfiguration文件中列出的每个堆栈authentication模块。 按照这个文件的指示,多个模块中的一个可能会失败,导致pam _…()调用返回一个错误。 在应用程序继续之前,最好也暂停一下。 这种延迟的主要原因是安全性:延迟的作用主要是阻止暴力字典攻击,但也有助于阻止定时(秘密信道)攻击。

这是一个非常简单,毫不费力地大大提高安全性的方法。 考虑:

  1. 系统A没有延迟。 攻击者有一个创build用户名/密码组合的程序。 以每分钟数千次的速度尝试每个组合并logging所有成功login只需几个小时。

  2. 系统B在每次不正确的猜测后都会产生5秒的延迟。 攻击者的效率已经降低到每分钟12次,有效地削弱了暴力攻击。 而不是几个小时,可能需要几个月才能find有效的login。 如果黑客是那个病人,他们会合法的。 🙂

失败的authentication延迟会降低login尝试的速度。 这个想法是,如果有人正在对一个人进行字典或暴力攻击,或者可能会要求攻击者等待失败延迟,从而迫使他花更多的时间,并给你更多的机会来检测它。

您可能也有兴趣知道,根据您使用的loginshell,通常有一种方法来configuration此延迟。

在GDM中,延迟在gdm.conf文件中设置(通常在/etc/gdm/gdm.conf中)。 您需要设置RetryDelay = x,其中x是以秒为单位的值。

现在大多数Linux发行版都支持在/etc/login.defs中定义FAIL_DELAY,允许您在login尝试失败后设置等待时间。

最后,PAM还允许您在auth线上设置nodelay属性来绕过失败延迟。 ( 这里是关于PAM和Linux的文章 )

我不认为这可以像答复所表明的那样简单。

如果对一个正确的密码的响应是(即时的)某个值,那么你是否只需要等到该值超过这个值就知道密码是错误的? (至less知道概率,这对于破解的目的来说是好的)无论如何,你会同时运行这个攻击……这是一个大的DoS欢迎垫吗?

我之前所尝试的似乎是行得通的,但实际上并没有; 如果你在意你必须检查维基编辑历史…

什么工作(对我来说), 既要降低pam_faildelay.so延迟= X在/etc/pam.d/login (我把它降低到500000,半秒)的值, 还要添加节点(前面有一个空间)到common-auth的行末,正如Gabriel在他的回答中所描述的那样。

auth [success=1 default=ignore] pam_unix.so nullok_secure nodelay

至less对我来说(debian sid),只有做出其中的一个修改,并不会将默认的延迟时间缩短到默认的3秒以下,不过可以通过改变/etc/pam.d/login中的值来延长延迟时间。

这种废话足以让一个成年男子哭泣!

在Ubuntu 9.10上,我也想到了新的版本,你正在寻找的文件位于

/etc/pam.d/login文件

编辑行:

auth可选pam_faildelay.so延迟= 3000000

改变数字3与另一个你可能想要的。

请注意,要进行“nodelay”authentication,我认为你应该编辑文件

将/etc/pam.d/common-auth

太。 在线上:

auth [成功= 1默认=忽略] pam_unix.so nullok_secure

添加“nodelay”到最后(不含引号)。 但是关于“节点式”的最终解释就是我所想的。

我想从开发人员的angular度添加一个说明。 虽然这不会是明显的肉眼聪明的开发人员会发现匹配时发现匹配查询。 目击者认为,一场成功的比赛会比一场失败的比赛完成得更快。 因为匹配function会将凭证与所有已知帐户进行比较,直到find正确的匹配。 换句话说,假设有100万个用户帐号按ID顺序排列, 001,002,003等等。 您的ID是43,001。 因此,当您input正确的用户名和密码时,扫描将停止在43,001,并将您login。如果您的凭据不正确,则会扫描所有1,000,000条logging。 双核服务器处理时间的差异可能在毫秒之内。 在具有5个用户帐户的Windows Vista上,这将在纳秒。

我同意。 这是一个任意的编程决定。 把延迟时间设置为一秒而不是三次并不会真正伤害密码的可破解性,而是使其更加用户友好。

从技术上讲,这种故意拖延是为了防止像“线性化攻击” (还有其他攻击和原因)的攻击

为了说明这种攻击, 考虑一个程序(没有这个故意的延迟),它检查一个input的序列,看它是否匹配正确的序列,在这种情况下恰好是“ xyba 。 为了提高效率,程序员决定一次检查一个字符,一旦发现不正确的字符就退出,在开始检查长度之前。

正确的串行长度将比不正确的串行长度需要更长的时间。 甚至更好(对于攻击者),具有第一个字符正确的序列号将比任何具有不正确的第一个字符的序列号更长。 等待时间的连续步骤是因为每次有一个循环,比较正确的input。

  • 因此,攻击者可以select一个四字符的string,并且以x开头的string占用最多的时间。 (通过猜测工作)
  • 攻击者可以将字符固定为x,然后改变第二个字符,这样他们会发现y取最长的字符。
  • 然后攻击者可以将前两个字符固定为xy,并改变第三个字符,在这种情况下,他们会发现b最长。
  • 攻击者可以将前三个字符固定为xyb,然后改变第四个字符,在这种情况下,他们会发现a最长。

因此,攻击者一次可以恢复连续的一个字符。

Linearization.java。

Linearization.docx,示例输出

序列号是四个字符长,每个字符有128个可能的值。 那么有128 4 = 2 28 = 268,435,456可能的连续剧 。 如果攻击者必须随机猜测完整的序列号,她会猜测序列号大概是2 27 = 134,217,728次,这是一个巨大的工作量 。 另一方面,通过使用上面的线性化攻击,每个字母平均只需要128/2 = 64个猜测,总预期工作约为4 * 64 = 2 8 = 256个猜测,这是一个微不足道的数量工作的。

大部分的书面武术都是从这个改编的(摘自Mark Stamp的“信息安全:原则和实践”)。 上面的计算也没有考虑到猜测正确的串行长度所需的猜测量。