我有一个验证“密码”字段并建议用户输入强密码的功能。我还有一个名为“密码强度”的标签,指的是密码的强度(非常弱,非常弱,中等等)。

我只是想知道是否有更好的方法可以重新输入密码。 -编写此代码。




 function chkPasswordStrength(txtpass,strenghtMsg,errorMsg)
   {
     var desc = new Array();
     desc[0] = "Very Weak";
     desc[1] = "Weak";
     desc[2] = "Better";
     desc[3] = "Medium";
     desc[4] = "Strong";
     desc[5] = "Strongest";
   
     errorMsg.innerHTML = ''
     var score   = 0;

     //if txtpass bigger than 6 give 1 point
     if (txtpass.length > 6) score++;

     //if txtpass has both lower and uppercase characters give 1 point
     if ( ( txtpass.match(/[a-z]/) ) && ( txtpass.match(/[A-Z]/) ) ) score++;

     //if txtpass has at least one number give 1 point
     if (txtpass.match(/\d+/)) score++;

     //if txtpass has at least one special caracther give 1 point
     if ( txtpass.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/) ) score++;

     //if txtpass bigger than 12 give another 1 point
     if (txtpass.length > 12) score++;

     strenghtMsg.innerHTML = desc[score];
     strenghtMsg.className = "strength" + score;
	 
	 if (txtpass.length < 6)
	 {
	 errorMsg.innerHTML = "Password Should be Minimum 6 Characters"
	 errorMsg.className = "errorclass"
	 }
	 
	 
   } 

 <style type="text/css">
             .strength0
            {
                width:200px;
                background:#B20E37;
                text-align: center;
                font-weight: bold;
            }
 
            .strength1
            {
                width:200px;
                background:#D32847;
                text-align: center;
                font-weight: bold;
            }
 
            .strength2
            {
                width:200px;
                background:#ff5f5f;
                text-align: center;
                font-weight: bold;
            }
 
            .strength3
            {
                width:200px;
                background:#83D680;
                 text-align: center;
                font-weight: bold;
            }
 
            .strength4
            {
                background:#4dcd00;
                width:200px;
                 text-align: center;
                font-weight: bold;
            }
 
            .strength5
            {
                background:#399800;
                width:200px;
                text-align: center;
                font-weight: bold;
            }
			
		  .errorclass
		  {
		  	font-weight:bold;
		  	font-size: 10px;
   		    color: #4F080B;
  		    font-family: Arial, 
		  }
</style> 

 <tr>
<%= label "Password",:mandatory=>true %>
<td>

<input id="user_password" type="password" size="30" name="user[password]"  onkeyup="chkPasswordStrength(this.value,document.getElementById('strendth'),document.getElementById('error'))">
                 
</td>

<td id="strendth" class="strength5"><b>Password Strength</td>
	
</tr>
<tr><td></td> 




评论

使用onkeyup =进行绑定的方式与使用eval相同。

您的逻辑有点缺陷。密码的强度不一定由其使用的字符集来定义。因此,密码“ abcdE1 $”的得分为“强”,而密码“ thisisaverylongpasswordbecause”的得分仅为“更好”,尽管更难于暴力破解(也许也很难通过“看别人”来获得)。肩膀”)。

@Bobby是否可以将所有这些字符(字母,特殊字符,数字)组合为正则表达式

必填:xkcd.com/936

嗨,我已经删除了代码挑战标签。该职位专用于特定职位(随时可以参加!)。

#1 楼


免责声明:我不是安全研究人员,下面的答案是基于我自己的谦虚知识得出的。数学是非常基础的,有许多要考虑的事项,如果有疑问,请向安全性咨询。此外,还有许多因素可能会完全破坏密码安全性,例如用户本身或社会工程。


在这种情况下,我不检查代码,而是检查您的代码。程序逻辑。

简短介绍密码安全性

首先定义您使用的规则(此处的“特殊字符”一词进一步指代!@#$%^&*?_~-()):


密码长度> 6:1点
密码长度> 12:1点
密码至少包含一个小写字母和一个大写字母:1点
/>密码至少包含一位数字:1点
密码至少包含一种特殊字符:1点

您的等级从0(非常弱)到5(最强)。这意味着基于长度的密码永远不能超过2(更好),但是短密码可以是4(很强)。如果我们牢记强密码不一定使用广泛的字符集,那么这是不好的。

以下密码被您的算法视为强密码:


abcdE $ 1
qwert!1
1111Aa @

现在,对于我来说,这些看起来并不强大,让我们看一下这种密码有多少种可能的组合。这些密码的总字符集为26(下)+ 26(上)+ 10(数字)+ 14(特殊)= 76.


76 ^ 7 =〜1.4 * 10 ^ 13 =〜14万亿美元


因此,知道字符集和密码长度的攻击者必须搜索大约14万亿个组合,直到找到密码。虽然,这是最坏的情况,可能是他们在第三次尝试中找到了它,但可能是倒数第二个。如今,计算机每秒可以进行5亿次猜测,这大约是8个小时...以任何方式都不能认为这是安全的。

让我们看看频谱的另一面,以下密码仅被认为是更好的密码:


thisisaverylongpassword因为(这是一个非常长的密码,因为)


它的字符集只有26个且长度为30(如果我已正确理解,则为系统的最大长度)。


26 ^ 30 =〜2.8 * 10 ^ 42 =〜2.8万亿个


我不知道这个数字是什么意思,所以让我们比较一下。好的,这也无济于事...也许如果我们将其放入一个时间范围内,每秒又进行5亿次猜测:


〜1.8 * 10 ^ 26年


这实际上是个好消息!那早在宇宙热死之前。

那么,废话少说多了:这里发生了什么?

密码的强度无法可靠地定义。但是我们知道两件事:


它越长,您必须经历的组合就越多。
它使用的字符越不同,就必须进行越多的组合。通过。

区别在于,一个添加到基数,另一个添加到指数。较高的指数比较高的基数重,并且产生更多的总组合。因此,只要有可能,就可以使用密码短语代替密码。

尽管看似容易受到字典攻击,但牛津字典却拥有30万个主要条目,因此,如果我们有4个单词的密码短语,那就是:


300000 ^ 4 = 8.1 * 10 ^ 21


而且,如果单词以大写,小写或混合以及不同的语言开头,则不会考虑可能的拼写错误。

使用户更喜欢密码短语,并且长而容易记住的密码比复杂的短密码更容易。

将其出售为功能!

这将使您的营销部门感到高兴,您刚刚实施了对软件中更安全的密码短语的支持!只需在密码框中添加简短信息,即可让您的用户了解它:


我们支持最多XX个字符的密码短语。

密码短语是


以及一些有关如何“创建”密码的简短信息,并在密码是否安全的情况下删除任何指示符。

您可以和谁不能提供帮助?

那里有很多用户组,问题是您想与谁联系?让我们定义三个组:


“普通用户”,它不理解为什么他们需要按下标记为“删除”的按钮才能删除某些内容。
普通用户,始终准备好学习,超越自己的视野。
技术用户已经使用了密码管理器和/或密码短语。

无论您多么努力,都将无法帮助“普通用户”。如果您告诉他们使用最小长度为6的密码,他们将使用“ 123456”或“ asdfgh”。如果您告诉他们使用最小长度为12的密码,他们将使用“ asdfghjkzxcvbn”或“ 000000000001”。它们超出了希望,将积极解决您实施的安全措施。

另一方面,“普通用户”已准备好学习新知识,向他们介绍密码短语,而您的支持将使他们希望使用密码短语。如果那时候的小帮助文本和系统的其余部分有帮助,他们将使用一个并非绝对愚蠢的密码。

“技术用户”会很高兴您支持XX长度的密码和密码短语。它们很可能已经使用了强壮且随机的密码以及密码管理器或密码短语,但是您不以任何方式对其进行限制会使它们感到满意。

不安全存储的安全密码是不安全的

密码或密码短语的好坏都没有关系,如果您不能安全地存储密码,则它们是不安全的。

我们将完全省去社会工程或“有害“用户(毕竟有些人的信用卡PIN放在同一个钱包的便条纸上),我们无济于事。

但是,如果有人设法闯入您的服务器,那么重要的是并且设法复制用户数据库,他们必须不能访问所有帐户。这可以通过使用适当的方法简单地对密码进行哈希处理来实现。即使攻击者现在拥有了所有用户名和电子邮件地址,密码仍然是安全的。

这也将使市场营销部门感到高兴,尽管您遭到了黑客攻击,但他们仍可以告诉用户,他们的帐户仍然安全(显然,建议您更改密码)。

好消息是,如果您对密码进行哈希处理,则完全没有理由完全限制密码长度!它们最终都将以相同长度的哈希表形式出现在您的数据库中,因此您可以让我用那本书中的那句话作为密码短语。

向正确的人问正确的问题

最后但并非最不重要的一点是,定义什么是强密码取决于很多事情。如果有疑问,请向安全人员支付一次拜访,这就是他们的目的。

评论


\ $ \ begingroup \ $
请注意,特殊字符检查很差。与典型的西方键盘相比,那里的特殊字符类型更多。最好检查是否有字母数字字符,而不是检查特定的非字母数字字符。
\ $ \ endgroup \ $
–cimmanon
2014年2月5日在15:13

\ $ \ begingroup \ $
长度不是密码安全最重要的部分吗?我看不到特殊字符/大小写如何使密码比暴力破解/鲁棒性更强健...(每个人都已看到对相关XKCD的队列引用)。
\ $ \ endgroup \ $
– HC_
2014年2月5日在21:04

\ $ \ begingroup \ $
@Bobby感谢您提供的合理答案。我很乐意看到您的逻辑加入代码!
\ $ \ endgroup \ $
– Pavan
2014年2月6日下午4:42

\ $ \ begingroup \ $
@HC_:我试图做到这一点,我是否失败了?
\ $ \ endgroup \ $
– Bobby
2014年2月6日在8:11

\ $ \ begingroup \ $
@Pavan:很难将其纳入代码。关于此主题,Securiy有很多问题。
\ $ \ endgroup \ $
– Bobby
2014年2月6日,9:20

#2 楼

正如Tim Seguine所提到的,如果您需要支持较旧的IE版本,请不要使用onkeyup,而应使用addEventListenerattachEvent

此外:不幸的是,chkPasswordStrength(txtpass,strenghtMsg,errorMsg)的名字被无用地取消了check的名称,txtpass可以简单地是password,而您的2个Msg参数不是消息,而是DOM元素。.

您最初是在清除errorMsg.innerHTML,但是您没有重置className,我会:

 if (txtpass.length < 6)
 {
   errorMsg.innerHTML = "Password Should be Minimum 6 Characters";
   errorMsg.className = "errorclass";
 }
 else
 {
   errorMsg.innerHTML = "";
   errorMsg.className = "";
 }


我也要写

 var desc = new Array();
 desc[0] = "Very Weak";
 desc[1] = "Weak";
 desc[2] = "Better";
 desc[3] = "Medium";
 desc[4] = "Strong";
 desc[5] = "Strongest";


as

var strengths = ['Very weak','Weak','Better','Medium','Strong','Strongest'];


评论


\ $ \ begingroup \ $
但是,我不同意最后一个,为什么不简单地使用var desc = new Array(“ Very Weak”,“ Weak”,...);。这很容易阅读,因为您不需要读到行尾就知道desc现在是一个数组...这也是一个不幸的名字。
\ $ \ endgroup \ $
– Bobby
2014-2-5 15:10



\ $ \ begingroup \ $
名字上的真对!@!虽然可以走得更远,但我想只有6个项目可以申请['','']
\ $ \ endgroup \ $
– konijn
2014年2月5日在15:13

#3 楼

您要重复很多CSS。让我们使用您的#strength ID进行修复。

<style type="text/css">
#strength {
    width: 200px;
    text-align: center;
    font-weight: bold;
}

.strength0 {
    background-color: #B20E37;
}

.strength1 {
    background-color: #D32847;
}

.strength2 {
    background-color: #ff5f5f;
}

.strength3 {
    background-color: #83D680;
}

.strength4 {
    background-color: #4dcd00;
}

.strength5 {
    background-color: #399800;
}

.errorclass {
    font-size: 10px;
    font-family: Arial;
    font-weight: bold;
    color: #4F080B;
}
</style>


注意:


请再次检查.errorclass的规则。您的font-family声明以,而不是;结尾。
我认为,应该始终在:值和属性声明之间留一个空格。它只是提高了可读性。
使用属性的简写时要注意。可能发生的情况的示例:如果编写background: red;,则不仅会将background-color设置为红色。它还为速记语法中可用的其他属性应用默认值(background-imagebackground-repeat,...)


评论


\ $ \ begingroup \ $
“您还将覆盖您之前所做的任何背景图像声明,依此类推”。忽略OP不使用图像的事实,那是怎么回事?即使是单个值,使用速记也比使用速记更短。 “这是一个好习惯,总是在:和value和property声明之间留一个空格”,这是胡扯,这两种方法都是有效的。
\ $ \ endgroup \ $
–cimmanon
2014年2月5日在17:45

\ $ \ begingroup \ $
@cimmanon我编辑了答案以更好地表达这些东西。更好?
\ $ \ endgroup \ $
– kleinfreund
2014年2月5日19:30在

\ $ \ begingroup \ $
@cimmanon审慎的空格使您拥有一个快乐的空间。
\ $ \ endgroup \ $
– David Harkness
2014年2月6日,下午3:42

#4 楼

Bobby对密码强度给出了很好的答案,因此我将重点放在代码上。

Reg ex

您具有以下正则表达式:

 /.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/
 


它匹配一个非换行符,后跟以下任意一个字符!,@,#,$,%,^,&,*,?,_,~或范围内的字符逗号到逗号或以下任何(,)。重复逗号,就好像它是分隔符一样。字符类不需要分隔符,因此将逗号放在字符类中只是意味着它将与逗号匹配。另一方面,破折号在字符类中具有特殊含义,因此,如果希望字符类包含破折号,则需要将其转义。

通常,我建议转义所有特殊字符在正则表达式中,如果要使用它们的字面值,它可以帮助您避免出现破折号之类的错误,并使意图更清楚。

在上下文中,您很少使用这样的字符,这似乎很奇怪。特殊角色类。对于此功能,将特殊字符定义为其他字符类中没有的任何字符似乎合乎逻辑:

 /[^A-Za-z0-9]/
 


或者,由于某种原因,如果您只希望基本的可打印ASCII特殊字符,则可以使用范围轻松地将它们全部包括在内(使用字符映射表来找到这样的范围):

 /[\ -\/\:-\@\[-\`\{-\~]/
 


以下是有关其工作原理的简短说明:

 /[         // start of the expression/range
  \ -\/    // All characters from " " to "/"
  \:-\@    // All characters from ":" to "@"
  \[-\`    // All characters from "[" to "`"
  \{-\~    // All characters from "{" to "~"
]/         // end the range/expression
 


函数调用

您在HTML中具有以下内容:

 <input id="user_password" type="password" size="30" name="user[password]" onkeyup="chkPasswordStrength(this.value,document.getElementById('strendth'),document.getElementById('error'))">
 


有些人想完全避免使用这样的内联代码,就我个人而言,是否内联一个简单的函数调用并不重要,但是将所有这些参数都包括在内有点令人讨厌,而且确实没有理由要拥有它们,您的函数可以很容易地获取相同的信息。

要考虑的另一件事是,不能保证keyup事件仅由于在字段中输入了内容而将触发。例如,如果用鼠标将某些内容粘贴到该字段中,则情况并非如此,并且我不确定您是否可以依靠keyup在所有使用屏幕键盘的设备上触发。无论如何,我都会通过在change事件上触发它来双重保护实时字段验证功能。

清除表

我不确定到底是什么Rails标签确实可以,但是如果在其位置呈现任何内容,则结果很可能是非法HTML,因此浏览器行为可能不一致。您可以将完整的表格放在另一个元素中,也可以将一个元素放在单个tdth元素内。通常不允许介于两者之间的任何内容。

#5 楼

您有1个支票(少于6个字符),该支票会给出错误,但是您要在所有非错误支票之后执行它。这意味着,如果我输入密码12345,即使为此完全无效,它也会给我1分。

您应该先将该支票移到所有其他支票上,如果失败则返回,因为现在,如果密码少于6个字符,您只会浪费宝贵的处理器速度。

除此之外,如果密码超过6个字符,您将得到1分,但密码少于6个字符时,您将得到错误信息。 。因此他们要么有观点,要么错误。所以你不能有0分。为什么会有一个0类别?

最后,您将DOM元素检索嵌入到HTML的函数调用中,应避免这种情况。我只是传递元素的名称,然后在函数本身中进行DOM检索。

评论


\ $ \ begingroup \ $
不,直到您证明它不是“有价值的处理器速度”。尽早进行检查更有意义:这是一项在阅读其余代码时不必做的心理检查。
\ $ \ endgroup \ $
– Quentin Pradet
2014年2月6日13:10

\ $ \ begingroup \ $
可能没有价值,但是如果不需要这些检查,您仍然在浪费处理器时间来进行检查。您应该始终先检查那些破坏或阻止功能的检查,以便如果检查返回false,则代码可以继续。如果您先处理所有内容,然后检查“哦,如果X则需要失败”,则您将处理时间花在了过时的流程上。如果您遇到了很多问题,该程序的响应速度似乎会稍慢,这有损于用户体验。
\ $ \ endgroup \ $
– Nzall
2014年2月6日下午13:28

\ $ \ begingroup \ $
我也同意您应该首先进行这些检查,但出于可读性原因。微观优化通常一文不值,在说“更快”之前先测量收益。用户无法注意到chkPasswordStrength的两个版本之间的任何区别。
\ $ \ endgroup \ $
– Quentin Pradet
2014年2月6日下午13:49

\ $ \ begingroup \ $
是的,性能提升不明显。也许我不应该提到这一点。但是尽管如此,即使您不会为了获得性能而这样做,但出于非可读性原因,您仍然应该这样做,即使该原因只是熟悉最佳实践。尽管此代码中没有严重延迟检查的内容,但其他代码中可能也包含那些检查(例如数据库或服务调用)。熟悉琐碎情况下的最佳路径的概念意味着您在非琐碎情况下也会习惯它,并且更有可能使用它。
\ $ \ endgroup \ $
– Nzall
2014年2月6日14:19