密码强度计[关闭]

Posted

技术标签:

【中文标题】密码强度计[关闭]【英文标题】:Password Strength Meter [closed] 【发布时间】:2010-10-31 04:41:25 【问题描述】:

我有一种情况,我希望能够在我的系统的 Web 界面中对用户密码进行评分,以便在他们点击提交之前,他们知道他们是否有错误的密码。

关键要求:

必须能够对密码进行评级,而不仅仅是通过/失败。 如果密码低于阈值,则应禁用表单,以便用户无法提交。 看起来不错。 :) 不使用 jQuery - 我们目前在这个系统中使用 Mochikit 和 Y!UI。

我发现许多用 jQuery 编写的密码计量器,以及诸如 http://www.passwordmeter.com/ 之类的内容过于冗长。

谁能推荐一个我可以使用的 javascript 密码评估器,或者举个例子来说明如何编写一个?

【问题讨论】:

看看github.com/dropbox/zxcvbn 这就是keepass在C#中的做法github.com/dlech/KeePass2.x/blob/… “因不具建设性而关闭”?我发现这确实很有建设性。查看超过 58,000 次,在 Google 排名中名列前茅,等等。来吧,伙计们...... 如果您确实使用密码强度计,请务必使用基本的完整性检查对其进行测试。 V4cc!nat!0n#3 是一个非常弱的密码(破解不到一个小时),而monitor coke cursor fat 非常强(破解了 146,000 个世纪)。使用给出了有效的结果(即复杂性要求使密码更弱,而不是更强) 【参考方案1】:

更新:在这里创建了一个 js fiddle 来观看它:http://jsfiddle.net/HFMvX/

我进行了大量的谷歌搜索,但没有找到任何令人满意的东西。我喜欢 passpack 的做法,所以基本上逆向工程了他们的方法,我们开始吧:

function scorePassword(pass) 
    var score = 0;
    if (!pass)
        return score;

    // award every unique letter until 5 repetitions
    var letters = new Object();
    for (var i=0; i<pass.length; i++) 
        letters[pass[i]] = (letters[pass[i]] || 0) + 1;
        score += 5.0 / letters[pass[i]];
    

    // bonus points for mixing it up
    var variations = 
        digits: /\d/.test(pass),
        lower: /[a-z]/.test(pass),
        upper: /[A-Z]/.test(pass),
        nonWords: /\W/.test(pass),
    

    var variationCount = 0;
    for (var check in variations) 
        variationCount += (variations[check] == true) ? 1 : 0;
    
    score += (variationCount - 1) * 10;

    return parseInt(score);

好的密码开始得分在 60 左右,这里的函数可以将其翻译成文字:

function checkPassStrength(pass) 
    var score = scorePassword(pass);
    if (score > 80)
        return "strong";
    if (score > 60)
        return "good";
    if (score >= 30)
        return "weak";

    return "";

你可能想稍微调整一下,但我发现它很适合我

【讨论】:

+1 因为此方法对密码的评分方式与 zxcvbn 相同,但代码更少:qwER43@! => 得分 70 = 好,Tr0ub4dour&amp;3 => 得分 80 = 强, correcthorsebatterystaple => 得分 86 = 强。 我已经用 php 重写了这个函数来检查服务器上的分数:pastie.org/8889985 查看@Ziggy 指出的grc.com/haystack.htm 并尝试该解决方案的最大弱点是它表示长度小于8 的密码在太小时是弱密码或好密码。在checkPassStrength(pass) 的顶部添加以下内容可以弥补if( pass.length &lt; 8 ) return "poor"; 的弱点,该弱点鼓励人们使用足够长的时间与混合字符,这些字符将根据时间长短变得弱、好或强。没有什么是真正的穷人。 这正是我要找的 sn-p。像这样的片段当你已经完成设计并且只是在寻找一个算法插件时会有所帮助.. 编辑:刚刚发现你不能在评论时对相同的文本使用粗体和斜体! 小问题:abcdefghijklmnopqrstuvwxyz 得分为 130。它应该检查黑客会想到的模式等。【参考方案2】:
Password Strength Algorithm:

Password Length:
    5 Points: Less than 4 characters
    10 Points: 5 to 7 characters
    25 Points: 8 or more

Letters:
    0 Points: No letters
    10 Points: Letters are all lower case
    20 Points: Letters are upper case and lower case

Numbers:
    0 Points: No numbers
    10 Points: 1 number
    20 Points: 3 or more numbers

Characters:
    0 Points: No characters
    10 Points: 1 character
    25 Points: More than 1 character

Bonus:
    2 Points: Letters and numbers
    3 Points: Letters, numbers, and characters
    5 Points: Mixed case letters, numbers, and characters

Password Text Range:

    >= 90: Very Secure
    >= 80: Secure
    >= 70: Very Strong
    >= 60: Strong
    >= 50: Average
    >= 25: Weak
    >= 0: Very Weak

设置 如果要更改密码中检查的内容,请切换为真或假

var m_strUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var m_strLowerCase = "abcdefghijklmnopqrstuvwxyz";
var m_strNumber = "0123456789";
var m_strCharacters = "!@#$%^&*?_~"

Check password


function checkPassword(strPassword)

    // Reset combination count
    var nScore = 0;

    // Password length
    // -- Less than 4 characters
    if (strPassword.length < 5)
    
        nScore += 5;
    
    // -- 5 to 7 characters
    else if (strPassword.length > 4 && strPassword.length < 8)
    
        nScore += 10;
    
    // -- 8 or more
    else if (strPassword.length > 7)
    
        nScore += 25;
    

    // Letters
    var nUpperCount = countContain(strPassword, m_strUpperCase);
    var nLowerCount = countContain(strPassword, m_strLowerCase);
    var nLowerUpperCount = nUpperCount + nLowerCount;
    // -- Letters are all lower case
    if (nUpperCount == 0 && nLowerCount != 0) 
     
        nScore += 10; 
    
    // -- Letters are upper case and lower case
    else if (nUpperCount != 0 && nLowerCount != 0) 
     
        nScore += 20; 
    

    // Numbers
    var nNumberCount = countContain(strPassword, m_strNumber);
    // -- 1 number
    if (nNumberCount == 1)
    
        nScore += 10;
    
    // -- 3 or more numbers
    if (nNumberCount >= 3)
    
        nScore += 20;
    

    // Characters
    var nCharacterCount = countContain(strPassword, m_strCharacters);
    // -- 1 character
    if (nCharacterCount == 1)
    
        nScore += 10;
       
    // -- More than 1 character
    if (nCharacterCount > 1)
    
        nScore += 25;
    

    // Bonus
    // -- Letters and numbers
    if (nNumberCount != 0 && nLowerUpperCount != 0)
    
        nScore += 2;
    
    // -- Letters, numbers, and characters
    if (nNumberCount != 0 && nLowerUpperCount != 0 && nCharacterCount != 0)
    
        nScore += 3;
    
    // -- Mixed case letters, numbers, and characters
    if (nNumberCount != 0 && nUpperCount != 0 && nLowerCount != 0 && nCharacterCount != 0)
    
        nScore += 5;
    


    return nScore;


// Runs password through check and then updates GUI 


function runPassword(strPassword, strFieldID) 

    // Check password
    var nScore = checkPassword(strPassword);


     // Get controls
        var ctlBar = document.getElementById(strFieldID + "_bar"); 
        var ctlText = document.getElementById(strFieldID + "_text");
        if (!ctlBar || !ctlText)
            return;

        // Set new width
        ctlBar.style.width = (nScore*1.25>100)?100:nScore*1.25 + "%";

    // Color and text
    // -- Very Secure
    /*if (nScore >= 90)
    
        var strText = "Very Secure";
        var strColor = "#0ca908";
    
    // -- Secure
    else if (nScore >= 80)
    
        var strText = "Secure";
        vstrColor = "#7ff67c";
    
    // -- Very Strong
    else 
    */
    if (nScore >= 80)
    
        var strText = "Very Strong";
        var strColor = "#008000";
    
    // -- Strong
    else if (nScore >= 60)
    
        var strText = "Strong";
        var strColor = "#006000";
    
    // -- Average
    else if (nScore >= 40)
    
        var strText = "Average";
        var strColor = "#e3cb00";
    
    // -- Weak
    else if (nScore >= 20)
    
        var strText = "Weak";
        var strColor = "#Fe3d1a";
    
    // -- Very Weak
    else
    
        var strText = "Very Weak";
        var strColor = "#e71a1a";
    

    if(strPassword.length == 0)
    
    ctlBar.style.backgroundColor = "";
    ctlText.innerhtml =  "";
    
else
    
    ctlBar.style.backgroundColor = strColor;
    ctlText.innerHTML =  strText;



// Checks a string for a list of characters
function countContain(strPassword, strCheck)
 
    // Declare variables
    var nCount = 0;

    for (i = 0; i < strPassword.length; i++) 
    
        if (strCheck.indexOf(strPassword.charAt(i)) > -1) 
         
                nCount++;
         
     

    return nCount; 
 

您可以根据自己的要求进行自定义。

【讨论】:

@garrow:编码风格除了和你的不一样还有什么问题? (FTR,这也不是我喜欢的风格,但那又怎样?) “2 个数字”发生了什么? :) 让我们尝试一个测试用例!根据***,比尔的密码是“123&$aA”,大约是 40 位熵。你的算法给它的分数是 80。Alice 的密码是“eriahrieudfklsvhnsreuilvnreuhgsldhhvf”,大约 160 位或熵。您的算法将其排在第 35 位。为了清楚起见,将这两个密码插入 grc.com/haystack.htm 给我们 0.7 秒的破解时间,而破解时间为 74.72 万亿万亿个世纪。 说真的。您根本不担心您多次投票的答案会建议使用较弱的密码而不是较强的密码?人们会复制粘贴这个! 所有其他选项都很棒,但决定密码强度的首要因素是长度。这应该反映在分数上。无论如何,我认为人们很容易定制这个。【参考方案3】:

以下是一组脚本: http://webtecker.com/2008/03/26/collection-of-password-strength-scripts/ (archived link)

我认为他们都对密码进行评分并且不使用 jQuery ......但我不知道他们是否具有禁用表单的原生支持?

【讨论】:

请记住,即使您在 javascript 中禁用了表单,您也应该在服务器端运行此检查。狡猾的用户无论如何都会提交表单,或者如果用户禁用了javascript怎么办? 您还应该注意,用户只是在欺骗他们自己。不确定您是否需要保护用户免受这种影响... 我认为您链接的页面被黑了...大声笑!讽刺 提供的链接无效..

以上是关于密码强度计[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

推特引导程序的jQuery密码强度计

ActionScript 3 AS3密码强度计

密码强度计

密码强度算法的标准化

如何检查密码强度? [关闭]

如何在 Ruby on Rails 中使用 Devise 验证密码强度?