Spring Security 暗号モジュール

Spring Security Crypto モジュールは、対称暗号化、キー生成、パスワードエンコーディングのサポートを提供します。コードはコアモジュールの一部として配布されますが、他の Spring Security(または Spring)コードには依存しません。

暗号化

Spring Security は、対称暗号器を構築するための AesGcmBytesEncryptor (Javadoc) AesCbcBytesEncryptor (Javadoc) を提供します。これらは、生の byte[] 形式のデータを暗号化するために使用できます。また、テキスト文字列を暗号化するために TextEncryptor (Javadoc) インスタンスを構築することもできます。これらの暗号器はスレッドセーフです。

BytesEncryptor と TextEncryptor はどちらもインターフェースです。BytesEncryptor には複数の実装があります。

BytesEncryptor

AesGcmBytesEncryptor を使用して、認証付き暗号化を備えた BytesEncryptor を構築します。

BytesEncryptor
  • Java

  • Kotlin

AesGcmBytesEncryptor.withPassword("password", "salt").build();
AesGcmBytesEncryptor.withPassword("password", "salt").build()

AesGcmBytesEncryptor は、ガロアカウンタモード(GCM)を使用した 256 ビット AES 暗号化方式を採用し、認証付き暗号化 [Wikipedia] (AEAD)を提供します。秘密鍵は PKCS #5 の PBKDF2(パスワードベース鍵導出関数 #2)を使用して生成されます。SecretKey の生成に使用したパスワードは安全な場所に保管し、共有しないでください。ソルトは、暗号化されたデータが漏洩した場合に鍵に対する辞書攻撃を防ぐために使用されます。また、16 バイトのランダムな初期化ベクトルが適用されるため、各暗号化メッセージは一意になります。

提供されるソルトは、16 進数でエンコードされた文字列形式で、ランダムで、長さが 8 バイト以上である必要があります。KeyGenerator を使用して、このようなソルトを生成できます。

キーを生成する
  • Java

  • Kotlin

String salt = KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded
val salt = KeyGenerators.string().generateKey() // generates a random 8-byte salt that is then hex-encoded

CBC モードが必要なユーザーは AesCbcBytesEncryptor を使用できます。

AesCbcBytesEncryptor
  • Java

  • Kotlin

AesCbcBytesEncryptor.withPassword("password", "salt").build();
AesCbcBytesEncryptor.withPassword("password", "salt").build()

このモードは認証されて [Wikipedia] おらず、データの真正性について一切保証しません。より安全な代替手段として、AesGcmBytesEncryptor をお勧めします。

TextEncryptor

テキストデータを暗号化するには、AesCbcBytesEncryptor を使用します。

TextEncryptor
  • Java

  • Kotlin

AesCbcBytesEncryptor.withPassword("password", "salt").build();
AesCbcBytesEncryptor.withPassword("password", "salt").build()

AesCbcBytesEncryptor はデータを生のバイト列として暗号化します。結果を 16 進数エンコードすることで、ファイルシステムやデータベースへの保存が容易になります。

クエリ可能なテキスト暗号化(同じ平文から常に同じ暗号文が生成される暗号化)は、固定の初期化ベクトルに依存し、十分なセキュリティを提供しないため、もはや推奨されません。代わりに、暗号化されたデータを照会するメカニズムをデータストアで探してください。

キージェネレーター

KeyGenerators (Javadoc) クラスは、さまざまな型のキージェネレーターを構築するための便利なファクトリメソッドを多数提供します。このクラスを使用すると、BytesKeyGenerator (Javadoc) を作成して byte[] キーを生成できます。また、StringKeyGenerator (Javadoc) を作成して文字列キーを生成することもできます。KeyGenerators はスレッドセーフなクラスです。

BytesKeyGenerator

KeyGenerators.secureRandom ファクトリメソッドを使用して、SecureRandom インスタンスに基づく BytesKeyGenerator を生成できます。

BytesKeyGenerator
  • Java

  • Kotlin

BytesKeyGenerator generator = KeyGenerators.secureRandom();
byte[] key = generator.generateKey();
val generator = KeyGenerators.secureRandom()
val key = generator.generateKey()

デフォルトのキー長は 8 バイトです。KeyGenerators.secureRandom バリアントは、キーの長さを制御します。

KeyGenerators.secureRandom
  • Java

  • Kotlin

KeyGenerators.secureRandom(16);
KeyGenerators.secureRandom(16)

KeyGenerators.shared ファクトリメソッドを使用して、すべての呼び出しで常に同じキーを返す BytesKeyGenerator を作成します。

KeyGenerators.shared
  • Java

  • Kotlin

KeyGenerators.shared(16);
KeyGenerators.shared(16)

StringKeyGenerator

KeyGenerators.string ファクトリメソッドを使用して、各キーを String として 16 進エンコードする 8 バイトの SecureRandom KeyGenerator を作成できます。

StringKeyGenerator
  • Java

  • Kotlin

KeyGenerators.string();
KeyGenerators.string()

パスワードエンコーディング

spring-security-crypto モジュールのパスワードパッケージは、パスワードのエンコードをサポートします。PasswordEncoder は主要サービスインターフェースであり、次の署名があります。

public interface PasswordEncoder {
	String encode(CharSequence rawPassword);

	boolean matches(CharSequence rawPassword, String encodedPassword);

	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}
}

rawPassword がエンコードされると、encodedPassword と等しい場合、matches メソッドは true を返します。この方法は、パスワードベースの認証スキームをサポートするように設計されています。

BCryptPasswordEncoder 実装は、広くサポートされている "bcrypt" アルゴリズムを使用してパスワードをハッシュします。Bcrypt はランダムな 16 バイトのソルト値を使用し、パスワードクラッカーを妨げるために意図的に遅いアルゴリズムです。4 から 31 までの値をとる strength パラメーターを使用して、実行する作業量を調整できます。値が大きいほど、ハッシュを計算するためにより多くの作業を行う必要があります。デフォルト値は 10 です。値はエンコードされたハッシュにも保存されるため、既存のパスワードに影響を与えることなく、デプロイされたシステムでこの値を変更できます。次の例では、BCryptPasswordEncoder を使用しています。

BCryptPasswordEncoder
  • Java

  • Kotlin

// Create an encoder with strength 16
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
// Create an encoder with strength 16
val encoder = BCryptPasswordEncoder(16)
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))

Pbkdf2PasswordEncoder 実装は、PBKDF2 アルゴリズムを使用してパスワードをハッシュします。パスワードクラッキングを打ち負かすために、PBKDF2 は意図的に遅いアルゴリズムであり、システムのパスワードを確認するのに約 0.5 秒かかるように調整する必要があります。次のシステムは Pbkdf2PasswordEncoder を使用しています。

Pbkdf2PasswordEncoder
  • Java

  • Kotlin

// Create an encoder with all the defaults
Pbkdf2PasswordEncoder encoder = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8();
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
// Create an encoder with all the defaults
val encoder = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))