用正则表达式作用户密码强度的经过性断定,过于简单粗暴,不但用户体验差,并且用户账号安全性也差。那么如何准确评价用户密码的强度,保护用户账号安全呢?本文分析介绍了几种基于规则评分的密码强度检测算法,并给出了相应的演示程序。你们能够根据本身项目安全性须要,作最适合于本身的方案选择。javascript
方案1算法经过密码构成分析,结合权重分派,统计得出密码强度得分。得分越高,表示密码强度越大,也就越安全。方案1算法思想简单,实现容易。java
1、密码长度:git
2、字母:github
3、数字:正则表达式
4、符号:算法
5、奖励:安全
根据密码评分,将密码划分红如下7个等级:ide
该评分标准及等级划分,实际使用时,可小作调整,但不建议作大的变更。工具
演示程序测试
// 评分 25,纯小写字母没法经过验证 console.log("aaaaaaaa".score()); // 评分 45,纯数字没法经过验证 console.log("11111111".score()); // 评分 47,小写+数字没法经过验证 console.log("aa111111".score()); // 评分 45,小写+大写没法经过验证 console.log("aaaaAAAA".score()); // 评分 50,4位密码不可能经过验证 console.log("11!!".score()); // 评分 70,5位密码可经过验证 console.log("0aA!!".score()); // 评分 67,小写+大写+数字可经过验证(8位) console.log("aA000000".score()); // 评分 70,数字+符号可经过验证 console.log("000000!!".score());
从以上测试结果中,咱们能够看出算法是十分的有效的,基本可以保证密码具备必定的安全性。可是存在的问题也很明显,其中最主要的问题是对重复或连续的字符评分太高。以测试用例中最后一个为例: 000000!!
能够获得70分,但显然并非一个很是强壮的密码。
另外,方案1最高能够获得95分,也就是说没有100分(绝对安全)的密码,这一点也是颇有智慧的设计。
针对方案1中的不足,方案2中引入了减分机制。对于重复出现,连续出现的字符给予适当的减分,以使得密码评分更准确。同时在方案2中密码的评分基数及计算过程都十分的复杂,要想理解其中每一步的含义,请保持足够的耐心。
1、密码长度:
2、大写字母:
3、小写字母:
4、数字:
5、符号:
6、位于中间的数字或符号:
7、最低条件得分:
其中最低条件的条目以下:
最低条件要求知足条目1并至少知足条目2-5中的任意三条。
1、只有字母:
2、只有数字:
3、重复字符数(大小写敏感):
该项描述复杂,具体计算方法见以下示例程序:
var pass = "1111aaDD"; //示意密码 var repChar = 0; var repCharBonus = 0; //得分 var len = pass.length; for(var i = 0; i < len; i++) { var exists = false; for (var j = 0; j < len; j++) { if (pass[i] == pass[j] && i != j) { exists = true; repCharBonus += Math.abs(len/(j-i)); } } if (exists) { repChar++; var unqChar = len - repChar; repCharBonus = (unqChar) ? Math.ceil(repCharBonus/unqChar) : Math.ceil(repCharBonus); } }
4、连续大写字母:
5、连续小写字母:
6、连续数字:
7、正序或逆序字母:
8、正序或逆序数字:
9、正序或逆序符号:
根据密码评分,将密码划分红如下5个等级:
// 评分 0 console.log("11111111".score()); // 评分 2 console.log("aa111111".score()); // 评分 38 console.log("000000!!".score()); // 评分 76 console.log("Asdf2468".score()); // 评分 76 console.log("Mary2468".score()); // 评分 60 console.log("@dmin246".score());
从以上测试能够看出方案2较方案1有了比较大的改进和提高,尤为是对连续或重复字符上表现出色。可是方案2也存在明显的不足,主要缺点包括对人名(Mary)、单词(Story)、键盘上相连的键(Asdf)、L33T(@dmin)无法识别。
L33T:是指把拉丁字母换成数字或是特殊符号的书写形式。例如把E写成三、A写成@、to写成二、for写成4。
针对方案2中的不足,引入了方案3,进一步的提长密码强度。方案3彻底引入一个第三方检验工具zxcvbn。
zxcvbn是一个受密码破解启发而来的密码强度估算器。它经过模式匹配和保守估计,大概能够识别大约30K左右的常规密码。主要基于美国人口普查数据,维基,美国电影,电视流行词以及其它一些经常使用模式,像日期,重复字符,序列字符,键盘模式和L33T会话等。
从算法的设计思想上,该方案彻底秒杀基于构成的统计分析方法(前两种方法)。同时zxcvbn支持多种开发语言。因其模式的复杂及字典的存在,当前版本的zxcvbn.js大约有800多K。
要了解项目的详情及算法见zxcvbn官网:
以上是三胖对密码强度检测算法和方案的理解和分析,不足之处还请你们多多指正!