如何衡量密码的强度?

Ora*_*ind 8 javascript php password-protection

我正在寻找一种有效的算法,可以让我准确了解密码的强度.

我发现几个不同的网站使用几种不同的算法,因为我在不同的网站上获得不同的密码强度等级.

Dar*_*nke 19

这已成为我在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]); 
}
Run Code Online (Sandbox Code Playgroud)

我的Jqueryish客户端密码计.目标应该是div.它的宽度将在0到100之间变化,背景颜色将根据脚本中指定的类进行更改.我发现的其他东西大部分都被盗了:

$.updatePasswordMeter = function(password,username,target) {
$.updatePasswordMeter._checkRepetition = function(pLen,str) {
res = ""
for ( i=0; i<str.length ; i++ ) {
    repeated=true;
    for (j=0;j < pLen && (j+i+pLen) < str.length;j++)
        repeated=repeated && (str.charAt(j+i)==str.charAt(j+i+pLen));
    if (j<pLen) repeated=false;
    if (repeated) {
        i+=pLen-1;
        repeated=false;
    }
    else {
        res+=str.charAt(i);
    };
};
return res;
};
var score = 0;
var r_class = 'weak-password';
//password < 4
if (password.length < 4 || password.toLowerCase()==username.toLowerCase()) { 
target.width(score + '%').removeClass("weak-password okay-password good-password strong-password"
).addClass(r_class);
  return true;
} 
//password length
score += password.length * 4;
score += ( $.updatePasswordMeter._checkRepetition(1,password).length - password.length ) * 1;
score += ( $.updatePasswordMeter._checkRepetition(2,password).length - password.length ) * 1;
score += ( $.updatePasswordMeter._checkRepetition(3,password).length - password.length ) * 1;
score += ( $.updatePasswordMeter._checkRepetition(4,password).length - password.length ) * 1;
//password has 3 numbers
if (password.match(/(.*[0-9].*[0-9].*[0-9])/))  score += 5; 

//password has 2 symbols
if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5; 

//password has Upper and Lower chars
if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/))  score += 10; 

//password has number and chars
if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/))  score += 15; 
//
//password has number and symbol
if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/))  score += 15; 

//password has char and symbol
if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/))  score += 15; 

//password is just a nubers or chars
if (password.match(/^\w+$/) || password.match(/^\d+$/) )  score -= 10; 

//verifing 0 < score < 100
score = score * 2;
if ( score < 0 )  score = 0;
if ( score > 100 )  score = 100;
if (score > 25 ) r_class = 'okay-password';
if (score > 50  ) r_class = 'good-password';
if (score > 75 ) r_class = 'strong-password';
target.width(score + '%').removeClass("weak-password okay-password good-password strong-password"
).addClass(r_class);
return true;
};
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用哈希密码填写哈希密码,那么彩虹表几乎是无用的. (3认同)

Eri*_* J. 7

从根本上说,您希望防止主要类型的攻击

  • 字典攻击
  • 蛮力攻击

要防止第一个,您要考虑包含常见单词弱的密码.为防止第二种情况,您需要鼓励合理长度的密码(通常为8个以上的字符)并使用相当大的字符集(包括字母,数字和特殊字符).如果您认为小写和大写字母不同,则会大大增加字符集.但是,这会为某些用户社区带来可用性问题,因此您需要平衡这一考虑因素.

一个快速的谷歌搜索发现了解决暴力攻击(复杂的密码)但不是字典攻击的解决方案.这个强度检查器列表中的 PHP密码强度计运行检查服务器端,因此可以扩展为检查字典.

编辑:

顺便说一下......你还应该限制每个用户的登录尝试次数.这将使两种类型的攻击不太可能发生.有效但非用户友好的是在X次尝试失败后锁定帐户并要求重置密码.更加用户友好但更省力的是节省登录尝试之间的时间.在最初的几次登录尝试之后,您也可以要求CAPTCHA(这是Stack Overflow在编辑太多后需要的,或者对于非常新的用户).