Javaでのパスワードのハッシュ化
1. 概要
このチュートリアルでは、パスワードハッシュの重要性について説明します。
それが何であるか、なぜそれが重要であるか、そしてJavaでそれを行うためのいくつかの安全な方法と安全でない方法を簡単に見ていきます。
2. ハッシュとは何ですか?
ハッシュは、cryptographic hash functionと呼ばれる数学関数を使用して、指定されたmessageから文字列またはhashを生成するプロセスです。
ハッシュ関数はいくつかありますが、パスワードをハッシュするように調整された関数には、安全を確保するために4つの主要なプロパティが必要です。
-
deterministicである必要があります:同じハッシュ関数で処理された同じメッセージは、always が同じhashを生成する必要があります
-
reversibleではありません:hashからmessageを生成することは実用的ではありません
-
entropyが高い:messageを少し変更すると、hashが大きく異なるはずです。
-
また、collisionsに抵抗します。2つの異なるmessagesが同じhashを生成することはありません。
4つのプロパティすべてを備えたハッシュ関数は、パスワードハッシュの強力な候補です。これらを一緒に使用すると、ハッシュからパスワードをリバースエンジニアリングする際の困難さが劇的に増加するからです。
また、ただし、password hashing functions should be slow。 高速アルゴリズムは、ハッカーが1秒あたり数十億(or trillions)の潜在的なパスワードをハッシュして比較することにより、パスワードを推測しようとするbrute force 攻撃を支援します。
これらすべての基準を満たす優れたハッシュ関数には、 PBKDF2, BCrypt, とSCrypt. がありますが、最初に、いくつかの古いアルゴリズムと、それらが推奨されなくなった理由を見てみましょう。
3. 推奨されません:MD5
最初のハッシュ関数は、1992年に開発されたMD5メッセージダイジェストアルゴリズムです。
JavaのMessageDigestを使用すると、これを簡単に計算でき、他の状況でも役立ちます。
ただし、過去数年間で、MD5 was discovered to fail the fourth password hashing property inは、衝突の生成が計算上簡単になったためです。 さらに、MD5は高速アルゴリズムであるため、ブルートフォース攻撃に対しては役に立ちません。
これらの理由から、MD5はお勧めしません。
4. 推奨されません:SHA-512
次に、1993年にSHA-0で始まったSecure HashAlgorithmファミリの一部であるSHA-512について見ていきます。
4.1. なぜSHA-512?
コンピューターの処理能力が向上し、新しい脆弱性が見つかると、研究者は新しいバージョンのSHAを導き出します。 新しいバージョンは次第に長さが長くなり、研究者は基礎となるアルゴリズムの新しいバージョンを公開する場合があります。
SHA-512は、アルゴリズムの第3世代で最も長いキーを表します。
there are now more secure versions of SHAの間、SHA-512 is the strongest that is implemented in Java。
4.2. Javaでの実装
それでは、JavaでSHA-512ハッシュアルゴリズムを実装する方法を見てみましょう。
まず、saltの概念を理解する必要があります。 簡単に言えば、this is a random sequence that is generated for each new hashです。
このランダム性を導入することで、ハッシュのentropyを増やし、rainbow tablesと呼ばれるコンパイル済みのハッシュリストからデータベースを保護します。
新しいハッシュ関数は大体次のようになります。
salt <- generate-salt;
hash <- salt + ':' + sha512(salt + password)
4.3. 塩の生成
ソルトを導入するために、java.securityのSecureRandom classを使用します。
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
次に、MessageDigest classを使用して、saltでSHA-512 hash関数を構成します。
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt);
これを追加すると、digestメソッドを使用してハッシュパスワードを生成できるようになります。
byte[] hashedPassword = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
4.4. なぜ推奨されないのですか?
塩と一緒に使用する場合、SHA-512 is still a fair option、but there are stronger and slower options out there。
また、ここで取り上げる残りのオプションには、構成可能な強度という重要な機能があります。
5. PBKDF2、BCrypt、およびScrypt
PBKDF2、BCrypt、およびSCryptは、3つの推奨アルゴリズムです。
5.1. なぜそれらが推奨されるのですか?
これらはそれぞれ低速であり、それぞれに設定可能な強度を持つという素晴らしい機能があります。
これは、コンピューターの強度が増すにつれて、we can slow down the algorithm by changing the inputs.が
5.2. JavaでのPBKDF2の実装
さて、salts are a fundamental principle of password hashingなので、PBKDF2にも必要です。
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
次に、PBEKeySpecとSecretKeyFactoryを作成し、PBKDF2WithHmacSHA1 algorithmを使用してインスタンス化します。
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
3番目のパラメーター(65536)は、事実上強度パラメーターです。 これは、このアルゴリズムが実行される反復回数を示し、ハッシュの生成にかかる時間を増やします。
最後に、SecretKeyFactory を使用してハッシュを生成できます。
byte[] hash = factory.generateSecret(spec).getEncoded();
5.3. JavaでのBCryptとSCryptの実装
したがって、一部のJavaライブラリはそれらをサポートしていますが、BCrypt and SCrypt support don’t yet ship with Javaであることがわかります。
これらのライブラリの1つは、Spring Securityです。
6. SpringSecurityによるパスワードハッシュ
JavaはPBKDF2とSHAの両方のハッシュアルゴリズムをネイティブにサポートしていますが、BCryptとSCryptのアルゴリズムはサポートしていません。
幸いなことに、Spring Securityには、PasswordEncoderインターフェースを介してこれらすべての推奨アルゴリズムがサポートされています。
-
MessageDigestPasswordEncoder はMD5とSHA-512を提供します
-
Pbkdf2PasswordEncoderはPBKDF2を与えます
-
BCryptPasswordEncoder は私たちにBCryptを与え、そして
-
SCryptPasswordEncoder は私たちにスクリプトを与えます
PBKDF2、BCrypt、およびSCryptのパスワードエンコーダーはすべて、パスワードハッシュの必要な強度を構成するためのサポートが付属しています。
Spring Securityベースのアプリケーションがなくても、これらのエンコーダーを直接使用できます。 または、Spring Securityでサイトを保護している場合は、DSLまたはdependency injectionを介して目的のパスワードエンコーダーを構成できます。
また、上記の例とは異なり、these encryption algorithms will generate the salt for us internallyです。 アルゴリズムは、後でパスワードの検証で使用するために、出力ハッシュ内にソルトを保存します。
7. 結論
そこで、パスワードハッシュについて深く掘り下げました。概念とその使用法を探る。
また、Javaでコーディングする前に、いくつかの履歴ハッシュ関数と現在実装されているハッシュ関数を確認しました。
最後に、Spring Securityにはパスワード暗号化クラスが付属しており、さまざまなハッシュ関数の配列を実装していることがわかりました。
いつものように、コードはavailable on GitHub.です