你的密码有多强大?

在最新的CPAN更新中,我链接到了Data::Password::zxcvbn这个新模块,它可以估算给定密码被破解的难度。该模块由Gianni Ceccarelli开发,是Dropbox的JavaScript实现(由Dan Wheeler编写)的移植。

工作原理

Dan Wheeler最初的博客文章详细解释了这一点,但这里是一个简短的总结。为了估算密码的强度,我们测量其。zxcvbn算法通过三个阶段估算密码的熵

  1. 匹配 - 将密码的一部分与诸如已知单词、序列、日期等模式进行匹配
  2. 评分 - 对每个匹配的模式,计算其熵
  3. 搜索 - 找到最低熵的非重叠匹配序列

例如,密码“baseball2005-59xH}”;zxcvbn将“baseball”与其流行单词字典中的单词匹配,因此其熵相当低。同样,“2005”将与年份模式匹配。另一方面,最后一部分“-59xH}”不在我们的单词列表中,也不匹配zxcvbn的任何常见模式,需要暴力猜测,这具有非常高的熵。因此,zxcvbn对密码的熵的伪代码如下

dictionary_entropy("baseball") + year_entropy("2005") + brute_force_entropy("59xH{")

一旦计算了密码的熵,zxcvbn会估算其他统计数据,如破解密码所需的猜测次数和密码破解时间。

安装

Data::Password::zxcvbn在CPAN上,因此可以使用您喜欢的CPAN客户端进行安装,如cpancpanm

$ cpanm Data::Password::zxcvbn

如何使用它

Data::Password::zxcvbn很容易使用。它导出名为password_strength的函数,该函数接受一个密码字符串参数。然后它返回一个包含关于密码强度有用信息的hashref。

例如,这个简短的脚本接受一个密码参数,并打印其估计的强度

#!/usr/bin/env perl
use Data::Password::zxcvbn 'password_strength';

my $est_strength = password_strength(shift @ARGV);
printf "Password strength [0-4]: %d, # guesses needed: %d\n",
       $est_strength->{score},
       $est_strength->{guesses},

score是一个介于0和4之间的值,表示估计的密码强度,其中0表示极其容易,4表示非常强大。guesses值是正确猜测密码所需的估计猜测次数。请注意,根据密码的加密方式和存储位置,攻击者可能每秒能够进行数十亿次猜测。因此,需要非常大的guesses数字才能被认为是安全的。将脚本保存为password-strength,我可以按如下方式运行它

$ ./password_strength foobar
Password strength [0-4]: 0, # guesses needed: 915

哦,不!我的密码“foobar”评分为0。我想它不是很强大。让我们再试一个我喜欢的示例密码

$ ./password_strength itsasecret
Password strength [0-4]: 1, # guesses needed: 29445

嗯,“itsasecret”的评分稍微强一点,但不是很强。让我们试一个UUID(由Data::UUID生成)

$ ./password_strength 7E943948-0C75-11E8-A90E-9860F82DAED4
Password strength [0-4]: 4, # guesses needed: -1

叮当叮当叮当,我们找到了一个赢家。UUID得到了最高的评分4,估计的猜测次数为无限大(-1)。但我永远不会记住它:我可能应该使用密码管理器。

检测脆弱的密码

一些密码看起来很强,但包含与用户相关联的数据,使它们变得脆弱。比如我的雇主域名

$ ./password_strength ziprecruiter.com
Password strength [0-4]: 4, # guesses needed: 949660000000

所以ziprecruiter.com被认为是一个强大的密码,但它对我的密码并不强大。我们如何检测这些脆弱密码的实例?

Data::Password::zxcvbn 的 password_strength 函数接受一个选项的散列作为第二个参数。其中一个选项叫做“user_input”,可以用来提供有关用户的数据,例如他们的姓名、出生日期等。我已经将脚本更新为从命令行读取这些信息。

#!/usr/bin/env perl
use Data::Password::zxcvbn 'password_strength';

my $est_strength = password_strength(shift @ARGV, { user_input => { @ARGV }});
printf "Password strength [0-4]: %d, # guesses needed: %d\n",
       $est_strength->{score},
       $est_strength->{guesses};

运行脚本并包含我的雇主数据,您会看到密码的强度现在被评为较低。

$ ./password_strength ziprecruiter.com employer ziprecruiter
Password strength [0-4]: 2, # guesses needed: 1010000

如果您在一个网络应用中使用 Data::Password::zxcvbn 作为用户注册表单(或密码重置功能)的一部分,您可以将用户的详细信息传递给 password_strength 以捕获这些脆弱密码的实例。对于拥有管理员权限的用户,您可能需要他们的 zxcvbn 密码分数最高(4)。这比开发自己的密码验证函数来检查密码是否达到最小长度、具有某些字符组合要更安全。

参考资料


封面图片来自 freepik

标签

David Farrell

David 是一位专业程序员,他经常 推文博客 关于代码和编程艺术。

浏览他们的文章

反馈

这篇文章有什么问题吗?请在 GitHub 上打开一个 issue 或 pull request 以帮助我们。