TL;DR
- 全ての文字種は基本的に使用可能にしろ(最低ASCII)
- かといって全部の種類を使うことみたいな制限はかけるな
- 1000桁とかならともかく、10文字以内みたいな制限はかけるな
- 保管方法はオレオレ実装するな
- 定期変更させるな
- 秘密の質問は捨てろ
始めに
SIerのような職種をしていると、当然企業がらみの新サービスを立ち上げることがままあるのですがそのような場合は基本的に”先行事例”という名の元に初回そんなに検討されたかもわからない仕様がそのまま引き継がれてしまうことが多いです。
その中でもパスワードのような明らかに共通で使いまわせる機能に関しては、要件・実装ともにそのまんま社内にあったシステムを使ってしまいがちで、まともな議論が行なわれることは稀・・・。その結果世の中に現代とも思えないような要件がごろごろしてて、それが必要なサービスだったときに回りまわって消費者の我々がイライラするわけです。
どうせパスワードのような部分はSIerのお客さんもそれほど踏み込んでこないので、こちらが説明をすると受け入れてくれることがほとんどなので、草の根運動として現代のあるべきパスワード要件を広めていきたいのが投稿趣旨となります。
ぶっちゃけ
以下の記事は全てNIST(米国立標準技術研究所)が発行したSP 800-63B(翻訳リンク。
翻訳版を作ってくださる、OpenId Foundationのような組織には感謝。)の抜粋、雑感となります。該当文書にはその他認証手法の整理など有益な情報が詰まっておりますので、興味をもたれた方はぜひご覧ください。
パスワード許容文字列の要件
-
文字種は全部許容しよう
当たり前ですが、パスワードの組み合わせは(使用可能文字種)^(文字数)
で表すことが出来るため、ブルートフォースアタックにも強くなり、ユーザーとしても思っていたパスワードが使えないことが無くなり利便性も向上します。
当たり前ですが平文でパスワードを露出することはありえないので、SQLインジェクションなどの問題にあたることもありません。(平文保管しているならそのほうがよっぽど問題です) -
文字種の強制はやめよう
こちらに関しては、結構な数のサービスが採用しているように思えますが、下記引用のように大体の場合において強制される文字種はパスワードの強度そのものをあげることに繋がりません。
研究者はユーザが構成ルールで課せられた要件に対してかなり予測可能な方法で応答することを示した.例えば,パスワードとして”password”を選択したユーザは,大文字と数字を含む要件を与えると,比較的高い確率で”Password1”を選択し,記号を要件に追加すると”Password1!”を選択する.
-
パスワードの長さに上限を設けない
後述の管理で記載しますが、パスワードは当然hashで保管されるものであり、元の長さに依存しません。このため明らかに処理への影響がでるレベルならともかく、パスワードに上限を設けないことが重要です。(パスフレーズとよく言いますが、シンプルな単語の羅列であっても十分な長さが確保されていれば強度は上がるため、そのような形式を受け入れられるようにすることは重要です) -
ブラックリストは作ろう
正直これはSIerとしては、顧客とブラックリストの内容をどう決定するか(アップデートしていくか)という事に関して合意を取りにくいので面倒なのですが、例えば毎年話題になるSplash Dateの危険なパスワード100選このあたりを参考にするのが手っ取り早いのではないでしょうか。(123456など本当に使うのかと驚きますね・・)
パスワード保管要件
当たり前ですがユーザーが入れたパスワードが正解なのかを判定するために何らかの形で保管する必要がありますが、その際保管形式は万が一データベースの情報が漏れたときやシステム保守の内部犯が発生した時に現実的に復元できないようにすることが非常に重要です。
必要な実装としては、
- 適切なhash関数 (当然暗号化ではありません)
- 十分な回数のストレッチング(繰り返しhash)
- ランダムなソルト
このあたりが必要な事項になりますが、どれも基本的なわりにオレオレで作った結果実は1回hashして終わりだったり、ランダムといいながらリストから選ぶだけのソルトだったりと色々問題のある実装が世に溢れています。
こんなところこそ車輪の再発明なんてしないで巨人のやることにお任せするべき事例で、手っ取り早いインターフェースが用意されているライブラリを選択すべきです。
BCryptあたりが無難かと思います。(以下Javaで使用する場合のSpringSecurityCryptoのmaven記載です。)
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
その他要件
-
定期変更
昨年にそこそこ話題になったので皆さん認識はしていると思いますが、現在パスワードの定期変更は非推奨になっています。理由としてはローテーションで結局同じのにしがちである、固定された末尾の数字を取り替えて対応するなど実は推測しやすいパスワードを選択しがちになるからというのが大きな理由です。 -
秘密の質問
こちらも現代では常識になりつつありますが、個人が忘れ得ないイベント記憶を問う質問
出身の中学校はどこですか?
などはSNSの普及により、誰でもうかがい知れる”秘密”といえないものになったという点から絶対に使ってはいけません。
まとめ
現代においてだれしもが使う機能に関しては専門家が必ず居て最新情報はどんどんアップデートされていっています。このような共通機能は設計ごとをするときは国外事例なども鑑みながら、1次ソースをなるべく確認して世の中動向にあった設計をして利便性・安全性を高めていきましょう。