PBKDF2とScryptの比較!初心者でもわかるパスワードのハッシュ化アルゴリズム解説
新人
「Spring Securityでパスワードのハッシュ化をしたいんですけど、PBKDF2とかScryptって何が違うんですか?」
先輩
「お、パスワードのハッシュ化に注目したんだね。PBKDF2とScryptはどちらもセキュアな方法だけど、特徴が少し違うんだ。」
新人
「なるほど…まず、パスワードのハッシュ化って何のために必要なんですか?」
先輩
「じゃあそこから順番に解説していこうか。基本から学べば理解しやすいよ。」
1. パスワードのハッシュ化とは?
パスワードのハッシュ化とは、ログイン時などに使われるユーザーのパスワードを、特定のアルゴリズムによって暗号化することです。ハッシュ化されたパスワードは、同じ入力から常に同じ出力が得られる一方で、元のパスワードを復元するのは非常に困難です。
ハッシュ化を行うことで、データベースが万が一攻撃された場合にも、ユーザーのパスワードそのものが漏洩するリスクを減らせます。ただし、ハッシュ化だけではなく「ソルト」や「ストレッチング」も合わせて行うことで、セキュリティをさらに高めることができます。
Spring Securityでも、パスワードハッシュ化はセキュリティの基本対策として推奨されており、PBKDF2・Scrypt・BCrypt・Argon2などがよく使われています。
2. PBKDF2とは?
PBKDF2とは、「Password-Based Key Derivation Function 2」の略で、パスワードから鍵を導出するためのアルゴリズムです。多くのフレームワークやライブラリでサポートされており、Spring Securityでも簡単に使用できます。
PBKDF2は「繰り返し回数(iteration count)」を指定することで、計算量を増やし、総当たり攻撃(ブルートフォースアタック)や辞書攻撃に対する耐性を高めます。
PBKDF2ではSHA-256などのハッシュ関数を内部で利用します。以下にPBKDF2を使った例を示します。
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
public class PasswordHashExample {
public static void main(String[] args) {
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
String rawPassword = "myPassword123";
String hashedPassword = encoder.encode(rawPassword);
System.out.println("ハッシュ化されたパスワード: " + hashedPassword);
}
}
ハッシュ化されたパスワード: {pbkdf2}...
PBKDF2はNIST(アメリカ国立標準技術研究所)でも推奨されており、古くから使われている信頼性の高い方式です。ただし、計算処理がCPUに依存しているため、GPUを使った攻撃に対してはやや脆弱です。
3. Scryptとは?
Scryptとは、PBKDF2の後に登場したハッシュ化アルゴリズムで、特に「メモリ使用量」を多くすることで攻撃の難易度を上げています。GPUによる大量並列処理に強いのが特徴です。
Spring Securityでも、2022年以降のバージョンでScryptを簡単に使えるようになっています。計算だけでなくメモリも多く消費するため、ハードウェアを使った攻撃者にとってコストが高くなります。
以下は、Scryptを使ってパスワードをハッシュ化する例です。
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
public class ScryptExample {
public static void main(String[] args) {
SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
String rawPassword = "myPassword123";
String hashedPassword = encoder.encode(rawPassword);
System.out.println("Scryptでハッシュ化: " + hashedPassword);
}
}
Scryptでハッシュ化: {scrypt}...
Scryptは、以下のような特徴を持っています。
- メモリ消費型のアルゴリズムで、ハードウェア攻撃への耐性が高い
- 並列処理がしづらく、ブルートフォース攻撃に強い
- パフォーマンスチューニングがPBKDF2よりも難しい
そのため、パスワードの安全性を特に重視したい場合や、クラウド上でのアプリケーション運用時にはScryptが有力な選択肢となります。
4. PBKDF2とScryptの違いとは?
PBKDF2とScryptはどちらもパスワードのハッシュ化に利用される安全なアルゴリズムですが、設計思想や攻撃に対する防御の仕組みが異なります。
まず、PBKDF2は主に「繰り返し回数(iteration)」で攻撃を防ぐ方式です。計算処理を重くすることで、ブルートフォース攻撃を時間的に困難にするという考え方に基づいています。処理はCPUベースで行われ、設定次第でセキュリティ強度をある程度調整できます。
一方、Scryptは「処理を重くする」だけでなく「メモリ消費も大きくする」ことでセキュリティを高めています。特に、GPUを使った大規模な総当たり攻撃(GPUクラスターによる攻撃)に対して耐性が高いです。
以下に、PBKDF2とScryptの技術的な比較を簡単にまとめます。
| 項目 | PBKDF2 | Scrypt |
|---|---|---|
| 登場時期 | 2000年代初期 | 2010年代初期 |
| 処理の重さ | 繰り返し回数により調整 | CPU+メモリ使用量で調整 |
| 攻撃耐性(GPU) | やや弱い | 非常に強い |
| 実装の容易さ | 多くのライブラリで対応済 | 対応しているが設定がやや複雑 |
| 標準化状況 | NISTで標準化 | 一部で採用されている |
このように、PBKDF2とScryptの違いは、処理のアプローチだけでなく、攻撃への防御戦略にも現れています。
5. PBKDF2とScryptのメリット・デメリット比較
次に、それぞれのアルゴリズムが持つメリット・デメリットについて比較していきましょう。
PBKDF2のメリット
- 古くから使われているため、信頼性が高い
- 多くのフレームワークやライブラリがサポートしている
- 設定が比較的シンプルで導入しやすい
PBKDF2のデメリット
- GPUによる攻撃に弱い(CPU依存の処理)
- メモリ使用量が少なく、ハードウェア的な攻撃には不利
Scryptのメリット
- メモリ消費が多く、GPU攻撃への耐性が非常に高い
- セキュリティレベルが高く、近年のクラウド環境に適している
Scryptのデメリット
- チューニングパラメータが複雑で設定に注意が必要
- 実装ミスや不適切な設定によるリスクがある
- 実行環境によっては処理が重くなる可能性がある
このように、PBKDF2とScryptにはそれぞれ特徴があり、開発環境やセキュリティ要件に応じて選択する必要があります。
6. どちらを使うべきか?初心者が判断するポイント
では、実際にSpring Securityでパスワードハッシュ化を実装するときに、PBKDF2とScryptのどちらを選べばよいのでしょうか?初心者が判断する際に見るべきポイントを紹介します。
選択基準1:扱いやすさ
初めてセキュリティ機能を実装する場合、PBKDF2は非常に導入が簡単で、多くの参考資料も存在します。Spring Securityではデフォルトのサポートもあり、トラブルも少ないため、まずPBKDF2から始めるのがおすすめです。
選択基準2:セキュリティ強度
クラウド上でサービスを提供する場合や、より高度な攻撃を想定したい場合にはScryptの方が優れています。GPUによる攻撃への耐性を重視するのであれば、Scryptを選ぶべきです。
選択基準3:実行環境のリソース
Scryptはメモリを大量に使うため、メモリに余裕のない環境では処理負荷が高くなる可能性があります。一方でPBKDF2はCPU中心の処理なので、軽量な構成でも安定して動作します。
これらをふまえて、以下のような判断が可能です。
- まずはPBKDF2で実装し、セキュリティ要件が高まった場合はScryptへ移行する
- 社内アプリや小規模サービスならPBKDF2、大規模クラウドサービスならScrypt
- Spring Securityの設定に慣れている開発者はScryptでも問題なし
Spring Securityでは、PBKDF2とScryptのどちらも簡単に設定できますが、初心者が最初に試すならPBKDF2がおすすめです。開発環境が整い、セキュリティに対する理解が深まった段階でScryptの導入を検討するとよいでしょう。
7. Spring SecurityでPBKDF2を使う方法
Spring Securityでは、PBKDF2によるハッシュ化を簡単に導入できます。Spring BootやGradleを使った環境でも設定は非常にシンプルです。まず、Pbkdf2PasswordEncoderクラスを利用することで、PBKDF2のアルゴリズムを使用できます。
以下に、Spring SecurityでPBKDF2を使ってパスワードをハッシュ化するサンプルコードを紹介します。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
// デフォルト設定では、SHA256が使用され、185000回の繰り返し
return new Pbkdf2PasswordEncoder();
}
}
この設定を行うことで、Spring Securityが使用するPasswordEncoderとしてPBKDF2が適用されます。
もし繰り返し回数やハッシュ長、ソルトサイズなどを細かく指定したい場合は、以下のようにカスタム設定が可能です。
return new Pbkdf2PasswordEncoder(
"secret", // ソルトのためのシークレットキー
200000, // 繰り返し回数
256, // ハッシュ長
Pbkdf2PasswordEncoder.SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256
);
このように、PBKDF2はSpring Security PBKDF2として多くの導入例があり、公式ドキュメントや参考資料も豊富です。初心者でも設定しやすく、安全性の高いハッシュ化が可能です。
8. Spring SecurityでScryptを使う方法
Scryptは、より強力なハッシュ化方式として注目されています。Spring SecurityでもSCryptPasswordEncoderを使うことで、簡単に導入できます。ただし、メモリやCPUへの負荷がPBKDF2より高いため、環境によってはチューニングが必要です。
以下は、ScryptをSpring Securityに設定する基本的なコードです。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new SCryptPasswordEncoder();
}
}
このコードで、Spring Security Scryptによるパスワードのハッシュ化が有効になります。
より詳細な設定を行うには、以下のようにパラメータを指定できます。
return new SCryptPasswordEncoder(
16384, // CPUコスト(N)
8, // メモリコスト(r)
1, // 並列度(p)
32, // キー長(バイト)
64 // ソルト長(バイト)
);
これらのパラメータはScryptの性能に大きく影響するため、運用環境に応じて慎重に選定する必要があります。特にクラウド環境では、実行リソースの制約を意識したチューニングが重要です。
Scryptは強力な保護を提供する一方で、開発段階でのテストや性能測定も重要となるため、PBKDF2よりもやや上級者向けと言えるでしょう。
9. ハッシュ化アルゴリズム選定時の注意点とベストプラクティス
最後に、Spring Securityにおけるハッシュ化アルゴリズムの選定時に注意すべき点や、初心者が知っておくと役立つベストプラクティスを紹介します。
1. ハッシュ化は必ず実装する
まず大前提として、ユーザーのパスワードを平文で保存することは絶対に避けなければなりません。Spring SecurityではPasswordEncoderを必ず使ってハッシュ化する設計にするべきです。
2. ソルトの自動付加を活用する
PBKDF2やScryptでは、毎回異なるソルトを付与することで、同じパスワードでも異なるハッシュ値が生成されます。Spring Securityではこの処理を自動で行ってくれるため、手動でソルトを管理する必要は基本的にありません。
3. 定期的なアルゴリズム見直し
セキュリティのベストプラクティスとして、数年おきにハッシュアルゴリズムの選定を見直すことが推奨されています。特に、より安全なアルゴリズム(例:Argon2など)が登場した場合には、検討対象とすべきです。
4. パスワード変更時に再ハッシュ化を行う
ユーザーがパスワードを変更するタイミングで、新しいアルゴリズムやより高い繰り返し回数を用いて再ハッシュ化する設計にしておくことで、古い方式の脆弱性に対処できます。
5. ハッシュ化方式を切り替えられる設計にする
DelegatingPasswordEncoderを使えば、複数のハッシュ方式を切り替えて対応できます。新旧のユーザーを一時的に共存させることも可能です。
@Bean
public PasswordEncoder passwordEncoder() {
String idForEncode = "pbkdf2";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
return new DelegatingPasswordEncoder(idForEncode, encoders);
}
これにより、ハッシュ方式の切り替えや移行をスムーズに行うことができ、将来的な拡張にも強くなります。
6. ハッシュ化方式は1つに固定しない
将来の変更を見越して、あらかじめ複数方式に対応できるようにしておくことが、ハッシュ化のベストプラクティスです。
以上のように、「Spring Security PBKDF2」や「Spring Security Scrypt」を導入する際には、ただ設定をするだけでなく、設計全体を通してセキュリティを意識することが大切です。