系统中对密码复杂度的校验是比较常见的工作,往往我们可以通过正则来实现,或者基于规则而实现特定的算法来满足需求。

下面我来介绍两个开源的解决方案。

1.使用vt-password来实现密码复杂度的检查

VT 密码是一个 Java 库,用于验证密码是否符合定义的规则集。 该库包括以下规则实现:

  • AllowedCharacterRule - 密码是否只包含特定的字符列表
  • AlphabeticalSequenceRule - 密码是否包含字母顺序
  • CharacterCharacteristicRule - 密码是否包含所需的字符类型组合
  • DictionaryRule - 密码是否与字典中的单词匹配
  • DictionarySubstringRule - 密码是否包含字典中的单词
  • DigitCharacterRule - 密码是否包含数字
  • HistoryRule - 密码是否与以前的密码匹配,支持散列
  • IllegalCharacterRule - 密码是否包含非法字符
  • LengthRule - 是一定长度的密码
  • LowercaseCharacterRule - 密码是否包含小写字符
  • NonAlphanumericCharacterRule - 密码是否包含非字母数字字符
  • NumericalSequenceRule - 密码是否包含数字序列
  • RegexRule - 密码是否与正则表达式匹配
  • RepeatCharacterRegexRule - 密码是否包含重复字符
  • SequenceRule - 密码是否包含键盘序列
  • SourceRule - 密码是否与来自另一个系统或来源的密码匹配
  • QwertySequenceRule - 密码是否包含 QWERTY 键盘序列
  • UppercaseCharacterRule - 密码是否包含大写字符
  • UsernameRule - 密码是否包含用户名
  • WhitespaceRule - 密码是否包含空格

如果你想在你的Maven构建中使用这个项目,请在你的pom.xml 中包含以下内容:

<dependency>
  <groupId>edu.vt.middleware</groupId>
  <artifactId>vt-password</artifactId>
  <version>3.1.2</version>
</dependency>

示例代码:

import edu.vt.middleware.crypt.util.Base64Converter;
import edu.vt.middleware.dictionary.ArrayWordList;
import edu.vt.middleware.dictionary.WordListDictionary;
import edu.vt.middleware.dictionary.WordLists;
import edu.vt.middleware.dictionary.sort.ArraysSort;
import edu.vt.middleware.password.*;

public class CheckDemo {
    public static void main(String[] args) {
        // 密码的长度必须在8至16位之间 【密码长达大于等于8位】
        LengthRule lengthRule = new LengthRule(8, 16);
        // 不允许密码中有空格
        WhitespaceRule whitespaceRule = new WhitespaceRule();

        // 控制密码所需混合字符类型的规则 【特殊字符,字母大写,字母小写,数字必须包含三项】
        CharacterCharacteristicsRule charRule = new CharacterCharacteristicsRule();
        // 密码中至少有1位数字
        charRule.getRules().add(new DigitCharacterRule(1));
        // 密码中必须包含至少1位非字母和数字的特殊字符
        charRule.getRules().add(new NonAlphanumericCharacterRule(1));
        // 密码中至少有一个大写字符
        charRule.getRules().add(new UppercaseCharacterRule(1));
        // 密码中至少有一个小写字符
        charRule.getRules().add(new LowercaseCharacterRule(1));
        // 要求至少满足前面的3条规则
        charRule.setNumberOfCharacteristics(3);

        //用于确定密码是否包含与该密码关联的用户名的规则【密码中不能包含用户名】
        UsernameRule usernameRule = new UsernameRule() ;

        // 不允许3个重复字符【不能包含三个连续的字母或者数字】
        RepeatCharacterRegexRule repeatRule = new RepeatCharacterRegexRule(3);


        // 不允许按字母顺序排列
        AlphabeticalSequenceRule alphaSeqRule = new AlphabeticalSequenceRule();
        // 不允许长度为3的数字序列
        NumericalSequenceRule numSeqRule = new NumericalSequenceRule(3,true);
        // 不允许qwerty序列
        QwertySequenceRule qwertySeqRule = new QwertySequenceRule();


        // 将所有规则分组到一个列表中
        List<Rule> ruleList = new ArrayList<Rule>();
        ruleList.add(lengthRule);
        ruleList.add(whitespaceRule);
        ruleList.add(charRule);
        ruleList.add(usernameRule) ;
        ruleList.add(alphaSeqRule) ;
        ruleList.add(numSeqRule) ;
        ruleList.add(qwertySeqRule) ;
        ruleList.add(repeatRule);

        //初始化密码校验器
        PasswordValidator validator = new PasswordValidator(ruleList);

        List<String> historyPwd = new ArrayList<>() ;
        PasswordData passwordData = PasswordData.newInstance(new Password("12abcdyuiOmm111"),"dsf",historyPwd,new HashMap<>()) ;

        RuleResult result = validator.validate(passwordData);
        if (result.isValid()) {
            System.out.println("Valid password");
        } else {
            System.out.println("Invalid password:");
            for (String msg : validator.getMessages(result)) {
                System.out.println(msg);
            }
        }
    }
}

vt-password的wiki地址

2.使用passay来实现密码复杂度的检查

Passay 建立在 vt-password 的成功基础上,并提供了全面且可扩展的功能集,其更方便,更可扩展,并且为国际化做好了准备。

通过根据可配置的规则集验证候选密码来强制执行密码策略。 Passay为常见情况提供了一套全面的规则,并通过简单的规则接口支持扩展。

如果你想在你的Maven构建中使用这个项目,请在你的pom.xml 中包含以下内容:

<dependency>
    <groupId>org.passay</groupId>
    <artifactId>passay</artifactId>
    <version>1.6.1</version>
</dependency>

示例代码:

import org.passay.*;

public class PassayDemo {

    public static void main(String[] args) {
        PasswordValidator validator = new PasswordValidator(
                new LengthRule(8, 32),   // 长度规则:8 - 16 位
                new CharacterCharacteristicsRule(3,
                        new CharacterRule(EnglishCharacterData.UpperCase, 1),  // 至少有一个大写字母
                        new CharacterRule(EnglishCharacterData.LowerCase, 1),  // 至少有一个小写字母
                        new CharacterRule(EnglishCharacterData.Digit, 1),     // 至少有一个数字
                        new CharacterRule(EnglishCharacterData.Special, 1)   // 至少有一个特殊字符
                ) ,
                new UsernameRule(),                   //检查密码是否包含用户名
                new RepeatCharacterRegexRule(3) ,  // 检查密码是否包含重复的ASCII字符
                new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 3, false),    // 不允许连续 3 个字母,按字母表顺序
                new IllegalSequenceRule(EnglishSequenceData.Numerical, 3, false) ,      //不允许 3 个连续数字
                new IllegalSequenceRule(EnglishSequenceData.USQwerty, 3, false),        //不允许 QWERTY 键盘上的三个连续相邻的按键所代表的字符
                new WhitespaceRule()   // 不允许包含空格
        ) ;
        RuleResult ruleResult = validator.validate(new PasswordData("abcqazqasdfjklkl:*(0")) ;
        if(ruleResult.isValid()) {
            System.out.println("Valid password");
        }else {
            System.out.println("Invalid password:");
            for (String msg : validator.getMessages(ruleResult)) {
                System.out.println(msg);
            }
        }
    }
}

更多请参考官方地址:http://www.passay.org/