テーブルにハッシュ化されたパスワードを保存する( bcrypt )

Claris FileMaker でカスタム App を作成した場合、アカウントやパスワードをどのように管理していますか?
標準のアカウント管理機能や外部認証を使う以外にも、テーブルにアカウントとパスワードを保存して運用するケースもあります。ログインから利用時のインタフェースにおける権限設定など、総合的で細かな実装スキルが必要になりますが、アカウントの管理・運用がやりやすくなる方法の一つです。

その際、テーブルにパスワードを保存していきますが、パスワードを平文で保存するのはセキュリティ上大いに問題があります。管理者としては初期パスワードを発行して通知した後は利用者が各自でパスワードを変更管理し、管理者はパスワードを知ることができないという運用が望ましいです。仮に FileMaker のフルアクセスの権限を持っていても、テーブルに保存されている利用者のパスワードはわからない状態にしたいところです。

そこで利用される方法が、パスワードをハッシュ化して保存する方法です。FileMaker には暗号化用の Crypt 関連の関数が用意されていてテキストを暗号化して保存することができます。ところがこの値は復号することができます。これは保存されているパスワードが暗号化されていても FileMaker のフルアクセスの権限があれば利用者のパスワードが解析されてしまう可能性があります。

復号化できないハッシュ化の処理は、 FileMaker の標準機能では MD5 やSHA512 形式などを使うことができます。これらでハッシュ化された値 は復号化はできませんが強度が充分ではなく、いわゆる「ブルートフォース攻撃」には脆弱とされています。そこで対策としてソルトやストレッチングを組み合わせて強度を上げて保存していく方法がとられています。

とはいえ、やはり MD5 や SHA512 形式では心配なのでもっと強度の強いハッシュ化をして保存したい場合の方法をご紹介いたします。

「 bcrypt 」を使ったパスワードのハッシュ化

現在多く使われているパスワードのハッシュ化形式は「 bcrypt 」です。レインボーテーブル攻撃に対抗するためのソルトを組み込み、ブルートフォース攻撃に対抗するための繰り返し回数もそなえるなど、現在デフォルトのパスワードハッシュアルゴリズムとして利用されています。

Web ビューアと JavaScript を使って bcrypt 形式のハッシュ化をする

この bcrypt 形式でハッシュ化するための方法は一般的な言語では標準的に実装されていますが、FileMaker では実装されていません。そこで FileMaker からも実行できるように、Web ビューアを使い Web ビューア上で JavaScript を実行させ、実行結果を FileMaker と連携することで bcrypt 形式でハッシュ化したパスワードをフィールドに保存したり、また、ログイン時など入力したパスワードと保存されているハッシュ化されたテキストと照合させることができるようになります。

入力されたテキストを bcrypt でハッシュ化

例えば、以下のように実装します。
まず、ハッシュ化するための HTML(JavaScript)ソースを保存するためのフィールドを追加します。フィールドには以下のような内容を記述していきます。

まず、bcrypt 形式でハッシュ化できる JavaScript のライブラリ「bcryptjs」(https://www.npmjs.com/package/bcryptjs)を参照します。node.js を用意しなくても、CDN 経由で bcryptjs を参照して利用できます。

<script src="https://cdnjs.cloudflare.com/ajax/libs/bcryptjs/2.4.3/bcrypt.min.js"></script>

そしてハッシュ化するための関数を記述します。

function hashUserInput(userInput) {

  dcodeIO.bcrypt.hash(userInput, 10) // 第二引数はストレッチング回数
    .then((hashedResult) => {
      FileMaker.PerformScript( 'setPassword', hashedResult + '|' + userInput);
    })
    .catch((error) => {
      FileMaker.PerformScript( 'callError', error );
    });
}

設定テーブルなどにハッシュ化用のスクリプトを保存する

FileMaker から「Web ビューアで JavaScript を実行」で「hashUserInput」を呼び出し、引数でハッシュ化したいパスワードを渡します。そしてハッシュ化されたパスワードは、Web ビューアから FileMaker のスクリプト「setPassword」が呼び出され、引数として返ってきます。

実行させるには、まず Web ビューアをハッシュ化処理を実行したいレイアウト上に配置します。JavaScript のみ実行させるためのものなので、目立たないように小さく配置しておいても大丈夫です。そして Web ビューアにオブジェクト名を設定し、オプションの「JavaScript による FileMaker スクリプトの実行を許可」にチェックをします。

FileMaker には上記を実行するため二つのスクリプトを用意します。まず、利用者がパスワードを入力し上記「hashUserInput」関数にパスワードを渡してハッシュ化させるためのスクリプトです。スクリプトには、以下のステップで登録したいパスワードを Web ビューアに渡します。

Web ビューアで JavaScript を実行 [ オブジェクト名:"bcrypt" ; 関数名: "hashUserInput" ; 引数: $password ]

そして、Web ビューアから呼び出される FileMaker のスクリプト「setPassword」で引数で返ってきたハッシュ化されたパスワードをフィールドに保存します。

フィールド設定 [ 利用者マスタ::パスワード ; Get ( スクリプト引数 ) ]

実装例:初期パスワード発行画面で、フッタ部に目立たないようにWebビューアを配置。

Webビューアの設定では、「 JavaScript による FileMaker スクリプトの実行を許可 」にチェックを入れる

ハッシュ化用のスクリプトを実行してフィールドに保存します。(通常は画面上に配置しませんが、わかりやすいようにあえて見えるようにしています)

入力したパスワードとハッシュ化して保存されたパスワードとの照合

また、ログインするときなど利用者が入力したパスワードとフィールドに保存されているハッシュ化されたパスワードが合致するかどうかの処理も、bcryptjs を利用して実行できます。

function hashUserCompare(input,password){

dcodeIO.bcrypt.compare(input, password, (err, result) => {
	  if (err) {
 FileMaker.PerformScript( 'callError', error );
	  }
	  if (result) {
 FileMaker.PerformScript( 'resultCompare', 1 );
	  } else {
FileMaker.PerformScript( 'resultCompare', 0 );
	  }
	});
}

これも、実行するために FileMaker に二つのスクリプトを用意します。まずログインするときなど利用者がパスワードを入力して利用者マスタのパスワードと照合するかどうかチェックするスクリプトです。

利用者が入力したアカウント情報に合致する利用者マスタを参照し、登録されているハッシュ化されたパスワードを取得して以下のように「Web ビューアで javaScript」を呼び出します。

Web ビューアで JavaScript を実行 [ オブジェクト名:"bcrypt" ; 関数名: "hashUserCompare" ; 引数: $inputPassword, $hashedPassword]

そして、Web ビューアから呼び出される FileMaker のスクリプト「resultCompare」で引数で返ってきた照合結果を元に処理を進めます。

If [ not Get ( スクリプト引数 )]
    レイアウト切り替え [ メニュー ]

Else
    カスタムダイアログを表示 [ "認証できませんでした" ]

End If

ログイン画面の例です。画面下部に目立たないように Web ビューアを配置しています。
上記照合処理を実施し、認証できた場合は次の画面に進むように実装します。

認証できたらメニューに移動させるなどの処理を実行。

ここからパスワードの変更などの画面に移動させ、上記の処理を組み合わせてユーザー自身が入力したパスワードをハッシュ化してフィールドに保存させるようにします。

最後に

上記の処理は、CDN 経由で bcryptjs を参照はしていますが、ハッシュ化処理そのものはローカル内で実行されているため、ハッシュ化させるために入力した元のパスワードがインターネットなど外部に漏れるようにはなっていないため安心です。 
bcryptjs ライブラリにはもっと様々なオプションが利用できる関数が用意されています。詳しくは参照先のURLをご覧ください。https://www.npmjs.com/package/bcryptjs

また、パスワードそのものの強度(文字数や文字種、変更頻度など)は割愛しています。総務省などからもガイドラインが発表されていますので、各々適切な運用を心がけていただければと思います。

Web ビューアとJavaScript の外部ライブラリ bcryptjs を「Web ビューアで JavaScript を実行」ステップを使い、現在のパスワードハッシュ化のデフォルトアルゴリズムである bcrypt 形式を利用する方法を紹介いたしました。ご参考下さい。