「ストレッチングハッシュとは?意味や仕組みは?(キーストレッチング:パスワードハッシュ化:ソルト:反復回数・セキュリティなど)」という疑問を持って、この記事にたどり着いた方も多いのではないでしょうか。
パスワードを安全に保存する仕組みを調べていくと、必ずと言っていいほど登場するのがストレッチングハッシュという言葉です。
なんとなく「セキュリティに関係がありそう」という印象は持っていても、具体的にどんな仕組みなのか、説明できる方は意外と少ないかもしれません。
実はストレッチングハッシュは、パスワード漏えい事件のニュースなどでもたびたび話題になる、非常に実用的な技術です。
この記事では、キーストレッチングの基本的な意味から、ソルトとの関係、反復回数の考え方、代表的なアルゴリズムまで、初心者の方にもわかりやすく整理して解説していきます。
読み終える頃には、なぜこの技術が現代のパスワード管理に欠かせないのか、きっと納得していただけるはずです。
ストレッチングハッシュとは?結論から解説
それではまず、ストレッチングハッシュの基本的な意味について解説していきます。
結論から言うと、ストレッチングハッシュとはハッシュ関数を何度も繰り返し適用することで、パスワードの解析にかかる時間や計算コストを意図的に増大させる技術のことです。
この処理のことを、一般的にキーストレッチングとも呼びます。
単純にパスワードを1回だけハッシュ化するだけでは、近年のコンピューターの計算能力をもってすれば、総当たり攻撃で簡単に破られてしまう恐れがあります。
そこでハッシュ化の処理を何千回、何万回と繰り返すことで、攻撃者が1つのパスワードを解析するのにかかる時間を大幅に引き延ばすわけです。
ストレッチングハッシュの基本的な意味
ストレッチングという言葉には「引き伸ばす」という意味があります。
その名の通り、1回のハッシュ処理にかかる時間を引き伸ばし、結果として全体の処理時間を長くする発想がベースになっています。
パスワード認証システムにおいては、ユーザーが入力したパスワードをそのまま保存するのではなく、ハッシュ関数を通してから保存するのが基本です。
ストレッチングハッシュは、このハッシュ化のプロセスをさらに強化するための追加の防御層と考えるとイメージしやすいでしょう。
なぜハッシュを繰り返す必要があるのか
現代のGPUや専用ハードウェアは、単純なハッシュ計算であれば1秒間に数十億回という単位で処理できてしまいます。
つまり、1回だけのハッシュ化では、パスワードの候補を片っ端から試す総当たり攻撃や辞書攻撃に対して、あまりにも無防備な状態になってしまうのです。
だからこそ、意図的に計算コストを引き上げる仕組みが必要になります。
ハッシュ化を1000回、10000回と繰り返すことで、攻撃者側の総当たり試行にかかる時間も同じ倍率で増加することになります。
一言でいうと解析コストを引き上げる技術
例えば、1回のハッシュ計算に0.001ミリ秒しかかからないとします。
これを10000回繰り返すストレッチング処理にすると、1回の認証にかかる時間はおよそ10ミリ秒程度になります。
ユーザーにとっては体感できないわずかな遅延ですが、何百万通りものパスワードを試す攻撃者にとっては、単純計算で1万倍の時間的コストがのしかかることになります。
この「正規ユーザーにはほぼ影響がないが、攻撃者には大きな負担になる」という非対称性こそが、ストレッチングハッシュの本質的な価値と言えるでしょう。
ストレッチングハッシュの仕組み
続いては、ストレッチングハッシュの具体的な仕組みを確認していきます。
仕組み自体はシンプルで、基本となるのはハッシュ関数の出力を、再びハッシュ関数の入力として使うというループ処理です。
この処理を指定した回数だけ繰り返すことで、最終的なハッシュ値が生成される流れになっています。
ハッシュ関数を繰り返し適用する流れ
まず、ユーザーが設定したパスワードに対して、SHA-256などのハッシュ関数を1回適用します。
次に、その出力結果を新たな入力として、もう一度同じハッシュ関数に通します。
この処理をあらかじめ決めた回数分、機械的に繰り返していくのが基本的な流れです。
最終的に得られたハッシュ値だけがデータベースに保存され、途中経過の値は一切残りません。
出力を次の入力に使うループ処理
擬似的なイメージとして、以下のような処理が繰り返されているとイメージしてください。
1回目、ハッシュ値=hash(パスワード)。
2回目、ハッシュ値=hash(1回目のハッシュ値)。
3回目、ハッシュ値=hash(2回目のハッシュ値)。
このように、前の結果を次の材料にする処理を、指定回数分ひたすら繰り返していきます。
ループの回数が増えるほど、逆算による解析は幾何級数的に難しくなっていく点がポイントです。
処理時間と安全性のバランス
ただし、回数を増やせば増やすほど良いというわけでもありません。
回数を増やしすぎると、正規のログイン処理そのものにも時間がかかってしまい、ユーザー体験を損なう可能性があります。
また、サーバー側のCPU負荷が高くなりすぎると、大量のログインリクエストをさばききれなくなるリスクもあるでしょう。
そのため、実際のシステム設計では、安全性と処理速度のバランスを取りながら適切な回数を設定することが求められます。
キーストレッチングとソルトの関係
続いては、キーストレッチングとよく一緒に語られる「ソルト」との関係を確認していきます。
ストレッチングハッシュについて調べると、必ずと言っていいほどソルトという単語も目にするはずです。
この2つは似ているようで役割が異なるため、しっかり区別して理解しておく必要があります。
ソルトとは何か
ソルトとは、パスワードをハッシュ化する際に付け加えるランダムな文字列のことです。
同じパスワードであっても、ユーザーごとに異なるソルトを付加することで、生成されるハッシュ値をそれぞれ異なるものにできます。
ソルトは主に、レインボーテーブル攻撃と呼ばれる、あらかじめ計算済みのハッシュ値一覧を使った攻撃を防ぐために使われます。
攻撃者があらかじめ用意した対応表が、ソルトによって役に立たなくなるイメージを持つとわかりやすいでしょう。
ソルトだけでは防げない攻撃
では、ソルトさえあればストレッチングは不要なのでしょうか。
結論として、それは誤りです。
ソルトは「事前計算された表を使い回す攻撃」には有効ですが、攻撃者が特定の1人のユーザーを狙って、その場で総当たり計算をする攻撃には無力だからです。
つまりソルトは攻撃の効率化を防ぐ役割であって、計算コストそのものを引き上げる役割は持っていません。
ソルトとストレッチングを組み合わせる理由
安全なパスワード管理においては、ソルトとストレッチングは両方とも必須の要素です。
ソルトで「使い回し攻撃」を防ぎ、ストレッチングで「1件ごとの解析コスト」を引き上げる。
この2つを組み合わせて初めて、実用的なレベルのパスワード保護が実現できるのです。
実際、後述するbcryptやArgon2といった代表的なアルゴリズムも、ソルトの付与とストレッチング処理をセットで内蔵する設計になっています。
反復回数の目安とセキュリティ強度
続いては、多くの方が気になる反復回数の目安について確認していきます。
ストレッチングハッシュの効果は、突き詰めれば反復回数(イテレーション数)によって大きく左右されます。
回数が多いほど安全性は高まりますが、その分だけ処理時間も伸びていきます。
反復回数が意味すること
反復回数とは、先ほど説明したハッシュ化のループ処理を何回実行するかを示す数値です。
例えば反復回数が10000回であれば、1回のパスワード認証のたびに、内部でハッシュ関数が1万回実行されることになります。
この回数は、システムのハードウェア性能が上がるにつれて、将来的に引き上げていく必要がある点も覚えておきましょう。
推奨される反復回数の目安
反復回数の推奨値は、使用するアルゴリズムによって異なります。
目安を表にまとめると、以下のようなイメージになります。
| アルゴリズム | 反復回数の目安 | 特徴 |
|---|---|---|
| PBKDF2(SHA-256) | 600000回程度 | 広く普及、GPU耐性はやや弱め |
| bcrypt | コスト係数10〜12 | 回数ではなく指数的なコスト係数で調整 |
| scrypt | パラメータ次第 | メモリ消費量を増やしてGPU攻撃に強い |
| Argon2 | 用途に応じて調整 | 現状もっとも推奨されることが多い |
あくまで目安であり、公式ガイドラインやライブラリの最新の推奨値を都度確認することが望ましいでしょう。
反復回数を増やす際の注意点
反復回数を増やすこと自体は、セキュリティ向上に直結する良い施策です。
ただし、サーバーのスペックやユーザー数によっては、認証処理の遅延が業務に影響を与えることもあります。
特にログインが集中する時間帯には、CPU使用率が急上昇し、サービス全体の応答速度が落ちてしまうリスクも考えられるでしょう。
そのため、本番環境に反映する前には、必ず負荷テストを行い、実際の処理時間を計測しておくことをおすすめします。
代表的なストレッチングアルゴリズム
続いては、実務でよく使われる代表的なアルゴリズムについて確認していきます。
ストレッチングハッシュを実装する際には、自前でループ処理を組むのではなく、既存の信頼できるアルゴリズムを利用するのが一般的です。
PBKDF2の特徴
PBKDF2は、古くから利用されている代表的なキーストレッチングアルゴリズムです。
指定したハッシュ関数を反復回数分繰り返すという、比較的シンプルな設計になっています。
実装のしやすさと歴史の長さから、今なお多くのシステムで採用されているのが特徴でしょう。
一方で、GPUによる並列計算に対しては、後述するアルゴリズムほど強い耐性を持たない点は理解しておく必要があります。
bcryptの特徴
bcryptは、パスワードハッシュ化専用に設計されたアルゴリズムで、非常に高い人気を誇ります。
内部にソルトの生成機能を持っており、開発者が別途ソルトを管理する手間を減らせる点も魅力です。
反復回数の代わりに「コスト係数」というパラメータを使い、係数を1上げるごとに計算量が倍増する仕組みになっています。
scryptとArgon2の特徴
scryptは、計算量だけでなくメモリ消費量も意図的に増やす設計が特徴です。
GPUや専用ハードウェアは大量の並列計算は得意でも、大量のメモリを同時に確保するのは苦手な傾向があります。
その弱点を突く形で、より強固な耐性を実現しているわけです。
そしてArgon2は、2015年のパスワードハッシュ化コンペティションで優勝したアルゴリズムで、現時点でもっとも推奨されることが多い選択肢と言えるでしょう。
計算量、メモリ量、並列度という3つのパラメータを個別に調整できる柔軟性も高く評価されています。
実装時に気をつけたいポイント
続いては、実際にストレッチングハッシュを導入する際の注意点を確認していきます。
仕組みを理解していても、実装の細部を誤ると、せっかくの対策が十分に機能しないこともあります。
適切なライブラリを選ぶ
まず大前提として、ハッシュ化処理を自作するのは避けるべきです。
自分でループ処理を書くこと自体は簡単でも、暗号学的な安全性を検証するのは非常に高度な専門知識が必要になります。
bcryptやArgon2など、広く実績があり、継続的にメンテナンスされている信頼性の高いライブラリを利用するのが基本方針となるでしょう。
ソルトの生成と保存方法
ソルトは、必ず暗号学的に安全な乱数生成器を使って生成する必要があります。
単純な連番や、日時から生成した値などをソルトとして使うのは避けましょう。
また、ソルト自体は秘密にする必要はなく、ハッシュ値と一緒にデータベースへ保存して問題ありません。
重要なのは、ユーザーごと、パスワード設定のたびに毎回異なるソルトを生成することです。
サーバー負荷とのバランス
ストレッチングハッシュの導入で最も難しいのは、セキュリティと利便性のバランス調整です。
反復回数や係数を高くしすぎるとサーバー負荷が増大し、逆に低すぎると解析耐性が不十分になってしまいます。
定期的にハードウェア性能の進化状況を確認し、パラメータを見直していく運用体制を整えておくことが理想的でしょう。
また、パラメータを変更した際には、既存ユーザーのパスワードハッシュをどう移行するかという設計も、あらかじめ検討しておく必要があります。
まとめ
今回は、ストレッチングハッシュとは何か、その意味や仕組みについて、キーストレッチングやソルト、反復回数の考え方まで幅広く解説してきました。
ストレッチングハッシュとは、ハッシュ関数を繰り返し適用することで、パスワード解析にかかるコストを大幅に引き上げる技術です。
ソルトと組み合わせることで、レインボーテーブル攻撃と総当たり攻撃の両方に対する耐性を高められる点も、重要なポイントとして押さえておきたいところでしょう。
反復回数やコスト係数は多ければ良いというものではなく、サーバー負荷とのバランスを見ながら適切に設定する必要があります。
実装にあたっては、PBKDF2やbcrypt、scrypt、Argon2といった信頼性の高いアルゴリズムを活用し、自作のハッシュ処理は避けることが安全性への近道です。
この記事が、ストレッチングハッシュへの理解を深める一助となれば幸いです。