パスワードの保存
ユーザー認証を行うアプリケーションであれば、パスワードを扱う機会は必ずあるはずです。
ユーザーのパスワードを扱うことは非常に重要であり、それを適切に管理することはさらに重要です。
アプリケーションが攻撃を受け、ユーザーのパスワードがインターネット上に流出してしまうという事態は、想像するだけでも恐ろしいものです。では、パスワードを安全かつベストプラクティスに則って保存するにはどうすればよいのでしょうか。いくつかの方法を見ていきましょう。
暗号化とハッシュ化
一見すると、暗号化はパスワードを安全に保存するための優れた解決策のように思えるかもしれませんが、完全に依存するのは問題があります。
暗号化は本質的に双方向の関数であり、パスワードを暗号化できるということは、当然ながら復号も可能であることを意味します。論理的には正しいですよね?そうでなければ、ユーザーのパスワードがデータベースに保存されているものと一致するかどうかを検証できないからです。
つまり、パスワードを復号できるという能力自体が大きなリスクとなります。サーバーが侵害され、パスワードの暗号文が流出した場合、それを復号するために必要な鍵素材まで奪われてしまう可能性が高いのです。
一方、ハッシュ化は一方向性であるため、パスワードの保存にははるかに適しています。一度ハッシュ化してしまえば、暗号文から元の平文に戻す関数は存在しません。この特性により、ハッシュはパスワードの保護に最適なのです。
すべてのハッシュが同じではない
パスワードをハッシュ化して保存すると決めたとしても、単にハッシュ関数を適用して終わり、というほど単純ではありません。
ハッシュにはさまざまな種類がありますが、過去10年間のコンピューティング技術の進歩を考慮すると、そのほとんどはパスワードの保存には適していません。
前述の通り、ハッシュは一方向関数であるため逆変換はできません。しかし、ハッシュ化は決定論的でもあります。つまり、十分な時間とリソースがあれば、攻撃者がブルートフォース(総当たり)攻撃によってハッシュを元の平文に戻せる可能性があるのです。
このため、ハッシュ関数は以下の2つのカテゴリーに分類されます。
- 暗号学的ハッシュ
- パスワードハッシュ
パスワードハッシュの重要な特徴は、「ワークファクター(作業係数)」を持つことです(単一の整数、または複数のパラメータで構成されます)。これは、ハッシュの計算にかかる負荷を定義するものです。
近年、CPUやGPUの性能が向上したことで、コンシューマー向けのハードウェアでもハッシュに対する大規模なブルートフォース攻撃が容易になりました。これは、ハッシュの安全性が時間の経過とともに低下していくことを意味します。
「ワークファクター」は、業界のトレンドに沿った方法でハッシュを保存するために使用されます。ハードウェアが高速化するにつれてアルゴリズムのワークファクターを上げ、ハッシュの解読により多くの時間と労力を要するようにします。例えば、最新のハードウェアで100ミリ秒かかるように設定するといった具合です。
つまり、実際には2〜3年ごとにワークファクターを引き上げる必要があるかもしれません。
実践的なセキュアコーディング
OWASP Top 10のようなソフトウェアの脆弱性を理解し軽減するためのセキュアコーディングガイドラインを確認しましょう。また、実践的なアプリシミュレーションを通じて学べるトレーニングミッションにもぜひ挑戦してください。