正则表达式在不应该接受P@ssW0rd作为密码时接受



注意:似乎我必须坚持一个行正则表达式,由于我使用的验证库(jquery验证引擎)

我有以下正则表达式:

((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$).{8,25})$

匹配以下内容:

Minimun of 8 characters
1 lowercase character
1 uppercase character
1 digit
1 special character

这里的问题是它接受:P@ssW0rdQw3rty*为有效密码。

上面的代码不应该通过验证。我想出了这两个表达,试图解决这个问题,但没有成功地将其纳入最终作品。

p[a@][s5]{2}w[o0]rd  // anything with password in it including leet variants
qw[e3]rty            // anything with qwerty in it including leet variant

规则应该是:不允许任何Password或Qwerty的变体出现在单词的开头或结尾

有什么想法如何把这些放在一起并使其工作吗?

你能像下面这样添加更多的否定向前看子句吗?

(?!p[a@][s5]{2}w[o0]rd) // prevents variants of "password"
(?!qw[e3]rty)           // prevents variants of "qwerty"

…获取(也加入起始锚):

^((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$)(?!p[a@][s5]{2}w[o0]rd)(?!qw[e3]rty).{8,25})$

这可能不像你想的那样工作,然而——为了确保有大写字符,你必须以大小写敏感的方式匹配,但是你的"password"one_answers"qwerty"表达式只有在你以大小写不敏感的方式匹配时才会工作。您可能需要将其更改为以下内容:

^((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$)(?![pP][aA@][sS5]{2}[wW][oO0][rR][dD])(?![qQ][wW][e3][rR][tT][yY]).{8,25})$

恶心!

老实说,我建议你从根本上重新考虑一下你的战略。

    你可以试着把"明显"的密码列入黑名单,但你永远不可能抓住所有的密码。"@5dfgHjkl"怎么样?无论你试图禁止什么,用户都可以发明一些"明显"但允许的东西。
  • 对于你禁止的每一个额外的东西,你都需要提出一个错误信息,向你的客户解释他们选择的密码有什么问题。他们不会喜欢尝试猜测你的验证函数。
  • 尽管您尝试强制密码强度,但它可能无法抵御将let -speak单词与数字后缀结合在一起的常见字典攻击。

如果你想尝试并鼓励更强的密码,为什么不包括当前密码强度的可视化显示,这样你的客户就可以看到他们的密码有什么问题?你甚至不需要写代码:网上有很多插件。

你可以在你的正则表达式中添加反向预测:

^((?=.*?d)(?=.*?[a-z])(?=.*?[A-Z])(?!p[a@][s5]{2}w[o0]rd$)(?!qw[e3]rty).{8,25})$
<<h3> Regex演示/h3>

您可以使用以下格式在Regex中创建'黑名单':

blacklisted_exp_1|blacklisted_exp_2| ... (original_expression)

当任何一个黑名单表达式匹配时,整个表达式将匹配,但只有当所有黑名单表达式不匹配时,原始表达式捕获组才会匹配。

在你的例子中,这将是:

qw[e3]rty|P[a@][s5]{2}W[o0]rd|((?=.*d)(?=.*[a-z])(?=.*[A-Z])(?!^1{1,5}[a-z]+$).{8,25})$

这里有一个更简单的例子,你可以在web控制台中尝试:

var regex = /foo|bar|([a-z]{3})/; // Matches all 3-letter words except foo and bar
"foo".match(regex); // ["foo", undefined]
"bar".match(regex); // ["bar", undefined]
"baz".match(regex); // ["baz", "baz"]

最新更新