我最近读的一篇博文(伯乐在线注:请看本文最后),是关于强制使用更复杂的密码。原作者说这是为了更安全,但我认为这些技术不是最好的方式,比起「实用」来说,显得很麻烦。
问题
你想实施更安全的密码,我懂。但是,
请停止强迫我使用你那糟糕的密码规则 🙁
不让这篇文章那么严肃,我在试图做到这一点。我只是因为那篇文章有了灵感写下我的想法,不是针对作者。总之我是在和每一个在自己的网站和服务器使用这些密码规则的人讲话。我讨厌这些类型的规则:
'password' => [ 'required', 'confirmed', 'min:8', 'regex:/^(?=S*[a-z])(?=S*[A-Z])(?=S*[d])S*$/', ];
密码必须包含 1 个大写字母,1 个小写字母和数字。
有了这样的一个规则,密码 Abcd1234
会通过你的有效性检测,但是 mu-icac-of-jaz-doad
不会。
我知道你大概是想让人们使用随机字符密码,像 i%Mk3c4n
,但是你的规则实际上并没有这样执行,这些密码是个麻烦事而且不安全,除非它们足够长——使得它们成为更麻烦的事。打出这些密码很痛苦,尤其是在那些你没有安装密码管理器的手机和计算机上。
其次,使用不安全密码的人依旧会使用愚蠢的密码(比如 Loverboy1964),
所以你没有帮助任何人。
停止强迫我使用你专制的规则并鼓励其他人这么做——我的密码是更好呢。
例子
那位博主允许使用的 2 个密码:
下面这两个是那位博主不允许使用的密码:
解决方案
我不知道,但是如果你真的想要执行一些比此列表上的密码更安全的东西,那就不要强制不必要的复杂模式。你的验证规则,还是会让人继续用的原密码中的大部分,只是增加一个大写字母,或两三个数字。
(注1:此处提到的密码列表,里面都是 123456 、password、qwerty 之类的「愚蠢密码」)
相反,为什么不提高密码所需的最小长度,禁止 3 位或更长的数字序列 /[0-9]{3,}/?
你可以在那之后往前走一小步,不允许同样的字符在一行(相邻)重复两次以上 /(.)1{2,}/
,而且还没有太多的麻烦。
这将消除大部分的困扰,并不会不必要地限制您的用户密码选择。
更新
更好的是,为什么不忘记所有这些规则,只使用一个最小密码强度要求。
来自 reddit 网友 sarciszewski 的建议:
我不明白为什么那么多人不用 Zxcvbn。
我们并不特别关心你的密码包含了什么,只要密码强度估计量足够好就行。想要用2000个’A’构成一个ASCII penis来检测,zxcvbn 不会提醒你密码不包含小写字母不能使用而让你失望。
相关漫画
密码强度 (xkcd)
《在 Laravel 中强制复杂密码的建议》(英文原文)
根据简单优雅的 Laravel 文档,我将快速介绍如何促进用户使用更好的密码。通过 Authentication 的标准文档,我们用一个注册表单来说明。在 Laravel 的 AuthController 中,我稍作了修改。
(伯乐在线补注:Laravel 是一个 PHP Web 开发框架。)
protected function validator(array $data) { $messages = ['password.regex' => "Your password must contain 1 lower case character 1 upper case character one number"]; return Validator::make($data, [ 'name' => 'required|max:255', 'email' => 'required|email|max:255|unique:users', 'password' => 'required|confirmed|min:8|regex:/^(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$/', ], $messages); }
使用文档 http://php.net/manual/en/function.preg-match.php 和 Laravel 文档的正则表达式规则,我可以设置一个表达式来检查这些字符,我还可以设置一个自定义消息如果失败。
通过这些微小的工作我们可以用一个错误消息来帮助用户设置更好的密码。