我是在寻找一种有效的算法,可以给我一个准确的想法如何强一个密码。

我发现有几个不同的网站使用几种不同的算法,因为我得到不同的密度的评级在不同的网站。

有帮助吗?

解决方案

这已成为我在PHP / MySQL中使用密码的最佳实践的一般大脑转储。 这里提出的想法通常不是我自己的想法,而是迄今为止我发现的最好的想法。


确保您对涉及用户信息的所有操作使用SSL。涉及这些表单的所有页面都应检查它们是否通过HTTPS进行调用,并拒绝以其他方式工作。

您可以通过简单地限制允许的登录失败次数来消除大多数攻击。

允许相对较弱的密码,但存储每个用户登录失败的次数,如果超过密码,则需要通过电子邮件验证验证码或密码。我将最大失败次数设置为5。

需要仔细考虑向用户呈现登录失败,以便不向攻击者提供信息。 由于用户不存在而导致登录失败,由于密码错误,应返回与登录失败相同的消息。提供不同的消息将允许攻击者确定有效的用户登录。

如果因使用有效密码登录太多而导致登录失败且登录次数过多且密码错误,请确保返回完全相同的消息。提供不同的消息将允许攻击者确定有效的用户密码。当被迫重置密码时,相当数量的用户只会将其恢复原状。

不幸的是,限制每个IP地址允许的登录次数是不切实际的。 AOL和大多数公司等多家提供商代理他们的网络请求。实施此限制将有效消除这些用户。


我发现在提交之前检查字典单词效率低,因为你必须在javascript中向客户端发送字典,或者每次字段更改发送ajax请求。我这样做了一段时间它工作正常,但不喜欢它产生的流量。

检查固有的弱密码减去字典单词是实用的客户端,有一些简单的javascript。

提交后,我检查字典单词和包含密码的用户名,反之亦然服务器端。非常好的词典可以随时下载,对它们的测试很简单。这里有一个问题是,要测试字典单词,您需要针对数据库发送查询,该数据库再次包含密码。我解决这个问题的方法是先用简单的加密方法加密我的字典,然后找到SALT,然后测试加密的密码。不理想,但优于纯文本,仅适用于物理机和子网上的人员。

一旦你对他们选择的密码感到满意,先用PHP加密,然后存储。以下密码加密功能也不是我的想法,但解决了许多问题。在PHP中加密可防止共享服务器上的人拦截您未加密的密码。每个用户添加一些不会改变的东西(我使用电子邮件,因为这是我的网站的用户名)并添加一个哈希(SALT是我每个站点更改的一个短常量字符串)增加了对攻击的抵抗力。因为SALT位于密码内,并且密码可以是任何长度,所以几乎不可能用彩虹表来攻击它。 或者,这也意味着人们无法更改他们的电子邮件,但您不能在不使每个人的密码失效的情况下更改SALT。

编辑:我现在建议使用 PhPass 而不是我在这里推出自己的功能,或者只是忘记用户登录并改为使用 OpenID

function password_crypt($email,$toHash) {
  $password = str_split($toHash,(strlen($toHash)/2)+1);
  return hash('sha256', $email.$password[0].SALT.$password[1]); 
}

我的Jqueryish客户端密码计。目标应该是div。它的宽度将在0到100之间变化,背景颜色将根据脚本中指定的类进行更改。

其他提示

从根本上您想要防止的主要类型的攻击

  • 字典攻击
  • 暴力攻击

以防第一个,你想要考虑的密码包含共同的词弱。防止第二,你想要鼓励密码的合理的长度(8+字是常见的),并带有相当大的字符组(包括字母、数字和特殊字符)。如果你考虑的情况下和大写字母是不同的,提高字符集大。然而,这将创建一个可用性问题对于某些用户群体所以你需要的平衡,考虑。

一个快速的谷歌搜索了解决方案账户为暴力攻击(复杂的密码),但不是字典的攻击。PHP密码强度计从 这个名单的力量跳棋 运行的检查服务器的端,因此它可以扩大到检查字典。

编辑:

顺便说一下...你也应该限制数量的登录尝试的每用户。这将使这两种类型的攻击的可能性较小。有效的,但不是用户友好的是要锁定一个帐户,之后X坏的企图,并需要密码重置。更多的用户友好,但更多的努力是节流阀之间的时间登陆的企图。你也可以要求 验证码 之后的头几登录尝试(这是堆叠溢出要求后,太多的编辑,或者非常新的用户)。

基本上,您可能希望使用正则表达式来验证密码的长度和复杂性。

使用javascript执行此操作的一个很好的示例可以在这里找到:

http://marketingtechblog.com/programming/javascript-password-strength/

为达人Schwenke指出, 你会更好的工作对安全的自己并不把这个放到用户手中.

但这是很好的提供一些提示用户如何强他的密码是因为 最好的方式来获得一个密码仍然是社会engenering.

所以你可以破解的一个小客户的侧脚本,检查用户密码的实力作为一种礼貌指标,在真正的时间。这块没有什么,但是给了他一个很好的温暖的感觉,当它变绿:-)

基本上你必须检查是收意义:如果检查了密码包含字母、数字并非按字母顺序排caracters,在一个合理数量。

你可以破解你自己的算法非常容易:只做10/10号:

  • 0是一个零的长度的密码;
  • +2对每8caracters在的密码(15应该是一个安全的长度);
  • +1所采用的一封信,+2的使用2个字母;
  • +1所采用的一个数字,+2的使用2的数字;
  • +1所采用的一个非按字母顺序排caracters,+2对2。

你不需要检查神圣的密码(有大写字母,在被定位特别caracters,等等),用户不是银行/军事/秘密服务/月python电影行业,是吗?

你可以代码,在一个小时在没有疯狂的javascript技能。

反正,有效的密码和移动的所有安全代码的服务器上面。如果你可以委托的认证(e。g:开ID),甚至更好。

我想不出一个特定的算法来检查密码的强度。我们所做的是定义几个标准,当密码遵循标准时,我们将其分数加1。当密码达到阈值时,密码很强。否则它很弱。

如果具有不同的throeshold,您可以定义许多不同级别的强度,或者您可以为特定条件定义不同的值。例如,如果密码有5个字符,我们加1,但如果它有10,那么我们加2。

这是检查

的标准列表

长度(8到12可以,越多越好) 包含小写字母 包含大写字母 大写字母不是第一个。 包含数字 包含符号 最后一个字符不是人类符号(例如:。或!) 看起来不像是一个词典。一些明智的密码破解包含单词和字母替换库(如Library - > L1br @ ry)

希望有所帮助。

不要自己动手!

加密专家不鼓励使用自己的加密技术原因应该是显而易见的。

出于同样的原因,不应该尝试将自己的解决方案用于测量密码强度的问题;这是一个非常严重的加密问题。

为了这个目的,不要为了创作一些大规模的正则表达而进入丑陋的事业;您可能无法考虑影响密码整体强度的几个因素。

这是一个难题

测量密码强度的问题存在相当大的困难。我对这个问题进行的研究越多,我越发现这是一个“单向”的研究。问题;也就是说,人们无法衡量“难度”。 (计算成本)有效破解密码 。相反,提供复杂性要求并衡量密码满足它们的能力更为有效。

当我们在逻辑上考虑问题时,“可破解性指数”是指“裂缝指数”。没有多大意义,听起来很方便。推动计算的因素很多,其中大部分都与用于破解过程的计算资源有关,因此是不切实际的。

想象一下,使用 John the Ripper (或类似工具)对付相关密码;破解一个像样的密码可能需要几天,破解一个好的密码可能需要几个月的时间,直到太阳烧毁以破解一个特殊的密码。这不是衡量密码强度的实用方法。

从另一个方向解决问题更容易管理:如果我们提供一组复杂性要求,则可以非常快速地判断密码的相对强度。显然,提供的复杂性要求必须随着时间的推移而发展,但如果我们以这种方式解决问题,则要考虑的变量要少得多。

可行的解决方案

Openwall提供了一个名为 passwdqc 的独立实用程序(大概是,代表密码质量检查器)。 Openwall开发商,Solar Designer,似乎确实是一位真正的加密专家(他的作品不言自明),因此有资格创作这样的工具。

对于我的特定用例,这是一个更有吸引力的解决方案,而不是使用生活在网络黑暗角落的错误构思的JavaScript代码段。

为您的特定需求建立参数是最难的部分。实施很容易。

实际例子

我在PHP中提供了一个简单的实现来提供快速启动。标准免责声明适用。

此示例假定我们将整个密码列表提供给PHP脚本。不言而喻,如果您使用真实密码(例如,从密码管理器中转出的密码)执行此操作,则应在密码处理方面采取极其谨慎的态度。只需将未加密的密码转储写入磁盘就会危及密码的安全性!

<代码> passwords.csv

"Title","Password"
"My Test Password","password123"
"Your Test Password","123456!!!"
"A strong password","NFYbCoHC5S7dngitqCD53tvQkAu3dais"

<代码>密码check.php

<?php

//A few handy examples from other users:
//http://php.net/manual/en/function.str-getcsv.php#117692

$csv = array_map('str_getcsv', file('passwords.csv'), [',']);

array_walk($csv, function(&$a) use ($csv) {
    $a = array_combine($csv[0], $a);
});

//Remove column header.

array_shift($csv);

//Define report column headers.

$results[] = [
    'Title',
    'Result',
    'Exit Code',
];

$i = 1;

foreach ($csv as $p) {
    $row['title'] = $p['Title'];

    //If the value contains a space, it's considered a passphrase.

    $isPassphrase = stristr($p['Password'], ' ') !== false ? true : false;

    $cmd = 'echo ' . escapeshellarg($p['Password']) . ' | pwqcheck -1 min=32,24,22,20,16 max=128';

    if ($isPassphrase) {
        $cmd .= ' passphrase=3';
    }
    else {
        $cmd .= ' passphrase=0';
    }

    $output = null;
    $exitCode = null;

    $stdOut = exec($cmd, $output, $exitCode);

    //Exit code 0 represents an unacceptable password (not an error).
    //Exit code 1 represents an acceptable password (it meets the criteria).

    if ($exitCode === 0 || $exitCode === 1) {
        $row['result'] = trim($stdOut);
        $row['exitCode'] = $exitCode;
    }
    else {
        $row['result'] = 'An error occurred while calling pwqcheck';
        $row['exitCode'] = null;
    }

    $results[$i] = $row;

    $i++;
}

$reportFile = 'report.csv';

$fp = @fopen($reportFile, 'w');

if ($fp !== false) {
    foreach ($results as $p) {
        fputcsv($fp, $p);
    }

    fclose($fp);
}
else {
    die($reportFile . ' could not be opened for writing (destination is not writable or file is in use)');
}

exit;

结果 report.csv

Title,Result,"Exit Code"
"My Test Password","Bad passphrase (too short)",1
"Your Test Password","Bad passphrase (too short)",1
"A strong password",OK,0

包装后新

我还没有在网上找到更全面的解决方案;不用说,我欢迎任何其他建议。

显然,这种方法对于某些用例(例如,“密码强度计”实施的“客户端”)并不理想。即使这样,使用上面概述的方法对服务器端资源进行AJAX调用也是微不足道的,该资源返回通过/失败响应,但是这样
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top