如何对安全密码执行验证。 char[] 上的正则表达式?
Posted
技术标签:
【中文标题】如何对安全密码执行验证。 char[] 上的正则表达式?【英文标题】:How can I perform validation on a secure password. Regular expressions on a char[]? 【发布时间】:2014-09-15 10:54:05 【问题描述】:这个问题是对这里问题的跟进:
Why is char[] preferred over String for passwords?
这个问题非常有助于理解为什么使用 char[] 而不是 String;但是,它没有解释如何以安全的方式对 char[] 执行密码验证。这就是我想在这里了解的。
简单来说,我需要检查密码是否满足以下要求:
至少包含一个大写字母 至少包含一个小写字母 至少包含一位数字 至少包含一个符号 至少为 n 个字符,但不超过 m现在我明白了如何使用正则表达式来执行验证......这些答案显示了如何做到这一点:
Regexp Java for password validation Password must be 8 characters including 1 uppercase letter, 1 special character, alphanumeric characters据我所知,正则表达式检查涉及使用字符串。使用它们似乎并不安全,因为字符串是不可变的,因此在使用它们后无法立即清除它们。另一方面,可以清除 char[]。
那么,如何对存储在 char[] 而不是字符串中的密码进行验证?
我可以遍历每个字符,但是我必须创建每个我想测试的集合。理想情况下,能够利用正则表达式会很有用。
在Java中,我可以通过以下方法进行正则表达式检查。
String.matches(String regex)
或者
Pattern pattern = Pattern.compile(String regex);
pattern.matcher(CharSequence testString).matches();
如您所见,这两种方法都不支持直接使用 char[]。
【问题讨论】:
没有这样做的经验,所以我不知道安全后果,但是,您可以编译自己的Pattern
并使用 matcher(CharSequence)
【参考方案1】:
我会尽量避免使用复杂的正则表达式,我会建议类似 -
boolean validatePassword(char[] password, int n, int m)
if (password == null || password.length < n || password.length > m)
return false;
boolean upper = false;
boolean lower = false;
boolean digit = false;
boolean symbol = false;
for (char ch : password)
if (Character.isUpperCase(ch))
upper = true;
else if (Character.isLowerCase(ch))
lower = true;
else if (Character.isDigit(ch))
digit = true;
else // or some symbol test.
symbol = true;
// This short-circuits the rest of the loop when all criteria are true.
if (upper && lower && digit && symbol)
return true;
return upper && lower && digit && symbol;
【讨论】:
谢谢!虽然这不使用正则表达式,但它仍然进行验证。我不知道Character.isLower/Upper/Digit()
功能。如果目标是清除密码,不应该将本地 char[] 清零吗?
@NickMiller 一般来说,我宁愿让调用者处理它。一旦此方法完成,您就知道密码仅作为密码有效(本身不是正确的密码),您实际上还没有对它进行任何操作(据此方法所知)。
如果我错了请纠正我,但是方法中的char []不是副本吗?而如果是副本,就应该清除掉,因为我们不想等到 GC 激活。
@NickMiller 好消息!你不正确。它不是副本。 Java 是按值传递,但 Object(s) 的值,包括 Array(s),是引用。
啊!我明白了,引用被复制了,但是两个引用都指向同一个内存! :)【参考方案2】:
只需遍历char[]
即可进行基本的密码接受验证
【讨论】:
【参考方案3】:您可以使用CharBuffer.wrap(char[])
以CharSequence
的形式访问char 数组。
Pattern.matches(regex, CharBuffer.wrap(myCharArray))
【讨论】:
【参考方案4】:Java 的正则表达式实现不需要 String
对象 - 您应该传递 CharSequence
。如果您不想从char[]
数组创建String
,您可以将数组包装在您自己的CharSequence
接口实现中。
【讨论】:
我喜欢这个,因为CharSequence
可以在后台包含一个可变的char[]
。我可以限制访问并提供一个函数来在我完成后清除数组。我唯一关心的是正则表达式函数是否存储字符数据。以上是关于如何对安全密码执行验证。 char[] 上的正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章
无法对 Azure 上的 API 管理执行资源所有者密码 OAuth2 身份验证