【Java】パスワード生成・検証(チェック)ライブラリPassayの紹介

パスワード生成・検証 Passayの紹介アイキャッチプログラム
スポンサーリンク

Webアプリケーションを作成していると、

  • ユーザが入力したパスワードがポリシーに沿っているか確認する
  • アプリケーション側でパスワードを生成してユーザに通知する

といった仕組みが必要になることがあります。

こうしたパスワードに関する面倒な機能を提供してくれるのが、今日紹介するPassayです。

かなり多機能なので、どんなことができるのか解説していきたいと思います。

なお、バージョンは記事を書いた時点(2021年9月12日)の最新である1.6.1を前提にしています。最新版はPassayの公式ページで確認してください。

Passayを利用するための準備

Passayを利用するための方法です。メジャーだと思う3種類を準備しました。

私はMavenを使いますが、この記事で書くソースファイルはどの方法でも動きます。

jarファイル

Passayのjarファイルは公式サイトのダウンロードページにあります。zipファイルかtar.gzファイルをダウンロードして解凍してください。

jarsフォルダのpassay-1.6.1.jarをclasspathに追加すればOKです。

Maven

pom.xmlのdependenciesタグにPassayの情報を追加します。

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

Gradle

build.gradleのdependenciesにPassayの情報を追加します。

dependencies {
    implementation 'org.passay:passay:1.6.1'
}

パスワードの検証・チェック

ユーザが入力したパスワードがポリシーに合っているかを確認するための方法です。

とりあえずサンプルコードをお見せします。

	private static void checkPassword(String password) {
		PasswordValidator validator = new PasswordValidator(
				// 長さは8文字から16文字まで
				new LengthRule(8, 16),

				// 1文字以上の大文字のアルファベットが必須
				new CharacterRule(EnglishCharacterData.UpperCase, 1),

				// 1文字以上の小文字のアルファベットが必須
				new CharacterRule(EnglishCharacterData.LowerCase, 1),

				// 1文字以上の数字が必須
				new CharacterRule(EnglishCharacterData.Digit, 1),

				// 1文字以上の記号が必須
				new CharacterRule(EnglishCharacterData.Special, 1),

				// 空白やタブはない
				new WhitespaceRule());

		RuleResult result = validator.validate(new PasswordData(password));
		if (result.isValid()) {
			System.out.println("妥当なパスワード");
		} else {
			System.out.println("不当なパスワード:");
			for (String msg : validator.getMessages(result)) {
				System.out.println(msg);
			}
		}
	}

このメソッドは、引数の文字列が妥当なパスワードなのか検証して、妥当なら「妥当なパスワード」、そうでないなら「不当なパスワード:」と不当な理由を表示します。(このままだと、不当な理由は英語です。後で日本語化する方法を説明します。)

何を持って妥当なのかを判定するために、Passayではorg.passay.Ruleを実装したクラスをPasswordValidatorに渡します。個々のルールの概要はコメントに書いた通りです。

PassayではRuleの理解が必要です。結構な数のRuleクラスがあるので、後で概要を説明します

ここでは、パスワードの検証を行うためにはPasswordValidatorにRuleを渡してインスタンスを生成し、validateメソッドを使うということだけ理解できればいいでしょう。

メッセージを日本語にする

パスワードが不当な理由を日本語化する方法です。

  1. エラーメッセージを日本語化したpropertiesファイルを作成する
  2. Propertiesにロードする
  3. Propertiesを引数にしてPropertiesMessageResolverを作成する
  4. PasswordValidatorインスタンスを作成する際にPropertiesMessageResolverを第一引数に渡す

ソースコードにするとこんな感じです。

Properties props = new Properties();
props.load(new FileInputStream("/path/to/passay.properties"));
MessageResolver resolver = new PropertiesMessageResolver(props);
PasswordValidator validator = new PasswordValidator(
  resolver, new LengthRule(8, 16), new WhitespaceRule());

passay.propertiesに必要な項目は以下のファイルの通りです。大変なので日本語訳はしていません・・・。全部を翻訳する必要はないので、利用するRuleに関連するところだけ翻訳して使ってください。

HISTORY_VIOLATION=Password matches one of %1$s previous passwords.
ILLEGAL_WORD=Password contains the dictionary word '%1$s'.
ILLEGAL_WORD_REVERSED=Password contains the reversed dictionary word '%1$s'.
ILLEGAL_DIGEST_WORD=Password contains a dictionary word.
ILLEGAL_DIGEST_WORD_REVERSED=Password contains a reversed dictionary word.
ILLEGAL_MATCH=Password matches the illegal pattern '%1$s'.
ALLOWED_MATCH=Password must match pattern '%1$s'.
ILLEGAL_CHAR=Password %2$s the illegal character '%1$s'.
ALLOWED_CHAR=Password %2$s the illegal character '%1$s'.
ILLEGAL_QWERTY_SEQUENCE=Password contains the illegal QWERTY sequence '%1$s'.
ILLEGAL_ALPHABETICAL_SEQUENCE=Password contains the illegal alphabetical sequence '%1$s'.
ILLEGAL_NUMERICAL_SEQUENCE=Password contains the illegal numerical sequence '%1$s'.
ILLEGAL_USERNAME=Password %2$s the user id '%1$s'.
ILLEGAL_USERNAME_REVERSED=Password %2$s the user id '%1$s' in reverse.
ILLEGAL_WHITESPACE=Password %2$s a whitespace character.
ILLEGAL_NUMBER_RANGE=Password %2$s the number '%1$s'.
ILLEGAL_REPEATED_CHARS=Password contains %3$s sequences of %1$s or more repeated characters, but only %2$s allowed: %4$s.
INSUFFICIENT_UPPERCASE=Password must contain %1$s or more uppercase characters.
INSUFFICIENT_LOWERCASE=Password must contain %1$s or more lowercase characters.
INSUFFICIENT_ALPHABETICAL=Password must contain %1$s or more alphabetical characters.
INSUFFICIENT_DIGIT=Password must contain %1$s or more digit characters.
INSUFFICIENT_SPECIAL=Password must contain %1$s or more special characters.
INSUFFICIENT_CHARACTERISTICS=Password matches %1$s of %3$s character rules, but %2$s are required.
INSUFFICIENT_COMPLEXITY=Password meets %2$s complexity rules, but %3$s are required.
INSUFFICIENT_COMPLEXITY_RULES=No rules have been configured for a password of length %1$s.
SOURCE_VIOLATION=Password cannot be the same as your %1$s password.
TOO_LONG=Password must be no more than %2$s characters in length.
TOO_SHORT=Password must be %1$s or more characters in length.
TOO_MANY_OCCURRENCES=Password contains %2$s occurrences of the character '%1$s', but at most %3$s are allowed.

パスワードの生成

パスワードの検証で使ったRuleのうち、CharacterRuleを利用してパスワードの生成ができます。

	private static String createPassword() {
		List<CharacterRule> rules = Arrays.asList(
				// 1文字以上の大文字のアルファベットが必須
				new CharacterRule(EnglishCharacterData.UpperCase, 1),

				// 1文字以上の小文字のアルファベットが必須
				new CharacterRule(EnglishCharacterData.LowerCase, 1),

				// 1文字以上の数字が必須
				new CharacterRule(EnglishCharacterData.Digit, 1));

		PasswordGenerator generator = new PasswordGenerator();

		// 上で設定したルールを満たす8文字のパスワードを生成
		String password = generator.generatePassword(8, rules);
		return password;
	}

このメソッドだと、CharacterRuleで指定した文字を利用したランダムな8文字の文字列が生成されます。各CharacterRuleごとに最低1文字は使われる設定です。

パスワード生成に関しては、CharacterRuleの配列を渡してgenerator.generatePasswordを使うことを覚えておけば良いでしょう。

Rule概要

Passayにはたくさんのルールがあります。全部を覚える必要はないので、必要になったら読み返してください。

ポジティブなRule

許容する設定を記述するルールです。

Ruleの名前概要
AllowedCharacterRule指定したcharの配列だけでパスワードが構成されている
AllowedRegexRule指定した正規表現を満たしている
CharacterCharacteristicsRule複数のCharacterRuleをまとめたRule、その中のいくつを満たせばいいか設定できる
CharacterRule指定したCharacterDataを持っている。最低限必要な文字数も設定できる
LengthRule必要な長さを設定できる
LengthComplexityRuleパスワードの長さごとに必要なルールを設定できる
ポジティブなルール

ネガティブなルール

許容しない設定を記述するルールです

Ruleの名前概要
DictionaryRule特定の文字列が完全一致した場合許容しない
DictionarySubstringRule特定の文字列が部分一致した場合許容しない
DigestDictionaryRule特定の文字列がハッシュ化した上で一致した場合した場合許容しない
HistoryRule以前使われたパスワードを許容しない
DigestHistoryRule以前使われたパスワードをハッシュ化して比較した上で許容しない
CharacterOccurrencesRule同じ文字が指定数以上使われた場合許容しない
IllegalCharacterRule指定した文字を含んでいた場合許容しない
IllegalRegexRule指定した正規表現を満たす場合許容しない
IllegalSequenceRule指定したSequenceDataで連続した場合許容しない(例えば12345など)
NumberRangeRule指定した範囲の数字を含んでいた場合許容しない
SourceRuleソースパスワードと一致した場合許容しない(HistoryRuleと似たような使い方?ちょっと良くわかりませんでした)
DigestSourceRuleソースパスワードとハッシュ化して比較した上で許容しない
RepeatCharacterRegexRule同じ文字が連続した場合許容しない
RepeatCharactersRule同じ文字の繰り返しを指定回数以上行った場合許容しない
UsernameRuleユーザ名を含んだ場合許容しない
WhitespaceRule空白(改行やタブも含む)を許容しない
ネガティブなルール

まとめ:Javaでパスワードの生成・検証を行うならPassayを使おう

パスワードの生成・検証を行う場合、Passayを使うと便利です。

もちろん正規表現などを用いて同じことをできるのですが、自分で作るよりすでに実績のあるライブラリを使うほうがバグも少なくなります。

あまりメジャーなライブラリではないので情報が少ないのは残念ですが、基本的な使い方はこの記事だけでもできるはずです。

利用する機会があったら参考にしてください。

おすすめ

せっかくJavaを勉強しているのなら、資格を取得してみませんか?OCJP(Oracle Certified Java Programmer) SilverはJavaの基本を学ぶのに適した資格です。初心者はもとより、中堅の人でも普段使わない機能を勉強するきっかけになると思います。

残念なことに試験は有料で、しかも結構高い(税抜26,600円)です。

しかし、お勤めの会社によっては費用を負担してくれるところもあるでしょうし、場合によっては報奨金まで出してくれるはずです。(私の会社は初回の試験料負担+報奨金を出してくれました)

私のおすすめな勉強方法は徹底攻略Java SE 11 Silver問題集を読むことです。問題集ですが、解説が充実しています。

徹底攻略Java SE 11 Silver問題集[1Z0-815]対応 徹底攻略シリーズ | 志賀 澄人 | 工学 | Kindleストア | Amazon
Amazonで志賀 澄人の徹底攻略Java SE 11 Silver問題集[1Z0-815]対応 徹底攻略シリーズ。アマゾンならポイント還元本が多数。一度購入いただいた電子書籍は、KindleおよびFire端末、スマートフォンやタブレットなど、様々な端末でもお楽しみいただけます。

大体30時間くらいの勉強で合格できました。

コメント

タイトルとURLをコピーしました