FIPS 140-2 サポート

FIPS 準拠のための Keycloak サーバーの設定方法

連邦情報処理規格出版 140-2 (FIPS 140-2) は、暗号モジュールを承認するために使用される米国の政府コンピュータセキュリティ規格です。Keycloak は FIPS 140-2 準拠モードでの実行をサポートしています。この場合、Keycloak はその機能のために FIPS 承認済みの暗号化アルゴリズムのみを使用します。

FIPS 140-2 で実行するには、Keycloak は FIPS 140-2 が有効になっているシステムで実行する必要があります。この要件は通常、インストール時に FIPS が有効になっている RHEL または Fedora を想定しています。詳細については、RHEL のドキュメントを参照してください。システムが FIPS モードの場合、基盤となる OpenJDK も FIPS モードになっていることを確認し、FIPS 対応のセキュリティプロバイダーのみを使用します。

システムが FIPS モードになっているか確認するには、コマンドラインから次のコマンドで確認できます。

fips-mode-setup --check

システムが FIPS モードでない場合は、次のコマンドで有効にできますが、システムはインストール時から FIPS モードになっていることが推奨されます。後から有効にするのではなく、次の手順で有効にしてください。

fips-mode-setup --enable

BouncyCastle ライブラリ

Keycloak は内部的に多くの暗号ユーティリティに BouncyCastle ライブラリを使用しています。Keycloak に同梱されているデフォルトの BouncyCastle ライブラリは FIPS 準拠ではないことに注意してください。ただし、BouncyCastle は FIPS 検証済みのバージョンのライブラリも提供しています。FIPS 検証済みの BouncyCastle ライブラリは、Keycloak の公式サポートを提供できないため、Keycloak に同梱されていません。したがって、FIPS 準拠モードで実行するには、BouncyCastle-FIPS ビットをダウンロードして Keycloak ディストリビューションに追加する必要があります。Keycloak が FIPS モードで実行されると、デフォルトの BouncyCastle ビットの代わりに BCFIPS ビットを使用し、FIPS 準拠を実現します。

BouncyCastle FIPS ビット

BouncyCastle FIPS は、BouncyCastle 公式ページからダウンロードできます。次に、それらをディストリビューションの KEYCLOAK_HOME/providers ディレクトリに追加できます。BouncyCastle Keycloak の依存関係と互換性のある適切なバージョンを使用してください。必要なサポートされている BCFIPS ビットは次のとおりです。

  • bc-fips バージョン 2.0.0。

  • bctls-fips バージョン 2.0.19。

  • bcpkix-fips バージョン 2.0.7。

  • bcutil-fips バージョン 2.0.3。

キーストアの生成

Keycloak サーバー SSL に使用する pkcs12 または bcfks キーストアを作成できます。

PKCS12 キーストア

p12 (または pkcs12) キーストア (および/またはトラストストア) は、BCFIPS 非承認モードで正常に動作します。

PKCS12 キーストアは、RHEL 9 上の OpenJDK 21 Java で標準的な方法で生成できます。たとえば、次のコマンドを使用してキーストアを生成できます。

keytool -genkeypair -sigalg SHA512withRSA -keyalg RSA -storepass passwordpassword \
  -keystore $KEYCLOAK_HOME/conf/server.keystore \
  -alias localhost \
  -dname CN=localhost -keypass passwordpassword

FIPS モードの pkcs12 キーストアは、秘密 (対称) 鍵を管理しません。この制限は、pkcs12 キーストアタイプ内でこのタイプの鍵を許可しない BCFIPS プロバイダーによって課せられます。

システムが FIPS モードの場合、FIPS 対応のセキュリティプロバイダーを使用するために、デフォルトの java.security ファイルが変更されるため、追加の構成は不要です。さらに、PKCS12 キーストアでは、keytool コマンドを使用するだけで PBE (パスワードベースの暗号化) 鍵を保存でき、Keycloak KeyStore Vault での使用や、KeyStore Config Source での構成プロパティの保存に最適です。詳細については、Keycloak の構成 および Vault の使用 を参照してください。

BCFKS キーストア

BCFKS キーストアの生成には、BouncyCastle FIPS ライブラリとカスタムセキュリティファイルの使用が必要です。

まず、/tmp/kc.keystore-create.java.security などのヘルパーファイルを作成します。ファイルの内容には、次のプロパティのみが必要です。

securerandom.strongAlgorithms=PKCS11:SunPKCS11-NSS-FIPS

次に、キーストアを生成するために、次のようなコマンドを入力します。

keytool -keystore $KEYCLOAK_HOME/conf/server.keystore \
  -storetype bcfks \
  -providername BCFIPS \
  -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
  -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
  -providerpath $KEYCLOAK_HOME/providers/bc-fips-*.jar \
  -alias localhost \
  -genkeypair -sigalg SHA512withRSA -keyalg RSA -storepass passwordpassword \
  -dname CN=localhost -keypass passwordpassword \
  -J-Djava.security.properties=/tmp/kc.keystore-create.java.security
自己署名証明書の使用はデモンストレーション目的のみであるため、本番環境に移行する際には、これらの証明書を適切な証明書に置き換えてください。

bcfks タイプのキーストア/トラストストアで他の操作を行う場合も、同様のオプションが必要です。

サーバーの実行

BCFIPS を非承認モードでサーバーを実行するには、次のコマンドを入力します。
bin/kc.[sh|bat] start --features=fips --hostname=localhost --https-key-store-password=passwordpassword --log-level=INFO,org.keycloak.common.crypto:TRACE,org.keycloak.crypto:TRACE
非承認モードでは、デフォルトのキーストアタイプ (およびデフォルトのトラストストアタイプ) は PKCS12 です。したがって、上記のように BCFKS キーストアを生成した場合、--https-key-store-type=bcfks コマンドも使用する必要があります。トラストストアを使用する場合も、同様のコマンドが必要になる場合があります。
すべてが期待どおりに動作する場合は、本番環境でロギングを無効にできます。

厳密モード

fips-mode オプションがあり、fips 機能が有効になっている場合、自動的に non-strict に設定されます。これは、BCFIPS を「非承認モード」で実行することを意味します。より安全な代替手段は、--features=fips --fips-mode=strict を使用することです。この場合、BouncyCastle FIPS は「承認モード」を使用します。このオプションを使用すると、暗号化とセキュリティアルゴリズムに関するセキュリティ要件が厳しくなります。

厳密モードでは、デフォルトのキーストアタイプ (およびデフォルトのトラストストアタイプ) は BCFKS です。別のキーストアタイプを使用する場合は、適切なタイプで --https-key-store-type オプションを使用する必要があります。トラストストアを使用する場合も、同様のコマンドが必要になる場合があります。

サーバーを起動する際に、起動ログに次のような Approved Mode に関するメモ付きの KC プロバイダーが含まれていることを確認できます。

KC(BCFIPS version 2.0 Approved Mode, FIPS-JVM: enabled) version 1.0 - class org.keycloak.crypto.fips.KeycloakFipsSecurityProvider,

厳密モードでの暗号化の制限

  • 前のセクションで述べたように、厳密モードは pkcs12 キーストアでは動作しない場合があります。前に述べたように、別のキーストア (bcfks など) を使用する必要があります。また、厳密モードを使用する場合、Keycloak では jks および pkcs12 キーストアはサポートされていません。例としては、管理コンソールで OIDC または SAML クライアントのキーストアをインポートまたは生成する場合や、レルムキーの java-keystore プロバイダーの場合などがあります。

  • ユーザーパスワードは 14 文字以上である必要があります。Keycloak はデフォルトで PBKDF2 ベースのパスワードエンコーディングを使用しています。BCFIPS 承認モードでは、PBKDF2 アルゴリズムでパスワードが少なくとも 112 ビット (実質的に 14 文字) である必要があります。短いパスワードを許可する場合は、SPI password-hashing のプロバイダー pbkdf2-sha512 のプロパティ max-padding-length を 14 に設定して、このアルゴリズムで作成されたハッシュを検証する際に追加のパディングを提供します。この設定は、以前に保存されたパスワードとの下位互換性もあります。たとえば、ユーザーのデータベースが非 FIPS 環境にあり、短いパスワードがあり、BCFIPS 承認モードで Keycloak でそれらを検証する場合、パスワードは機能するはずです。したがって、サーバーを起動する際に、次のようなオプションを効果的に使用できます。

--spi-password-hashing-pbkdf2-sha512-max-padding-length=14
上記のオプションを使用しても、FIPS 準拠は損なわれません。ただし、長いパスワードはどのみち良い習慣であることに注意してください。たとえば、最新のブラウザによって自動生成されたパスワードは、14 文字より長いため、この要件を満たしています。max-padding-length のオプションを省略する場合は、レルムのパスワードポリシーを 14 文字以上のパスワードにするように設定できます。
Keycloak 24 より前のバージョンから移行する場合、またはデフォルトのハッシュアルゴリズムをオーバーライドするためにパスワードポリシーを明示的に設定した場合、一部のユーザーが pbkdf2-sha256 のような古いアルゴリズムを使用している可能性があります。この場合、古い pbkdf2-sha256 でパスワードをハッシュしたユーザーがログインできるように、--spi-password-hashing-pbkdf2-sha256-max-padding-length=14 オプションを追加することを検討してください。これは、パスワードが 14 文字より短い可能性があるためです。
  • 1024 ビットの RSA 鍵は機能しません (2048 ビットが最小です)。これは、Keycloak レルム自体 (管理コンソールの Keys タブのレルムキー) によって使用されるキーだけでなく、クライアントキーおよび IDP キーにも適用されます。

  • HMAC SHA-XXX 鍵は、少なくとも 112 ビット (または 14 文字) である必要があります。たとえば、クライアント認証 Signed Jwt with Client Secret (または OIDC 表記では client-secret-jwt) で OIDC クライアントを使用する場合、クライアントシークレットは少なくとも 14 文字である必要があります。セキュリティを向上させるために、Keycloak サーバーによって生成されたクライアントシークレットを使用することをお勧めします。これは常にこの要件を満たしています。

  • bc-fips バージョン 1.0.2.4 は、PKCS 1.5 RSA 暗号化の移行期間の終了に対処します。したがって、アルゴリズム RSA1_5 を使用した JSON Web Encryption (JWE) は、デフォルトでは厳密モードでは許可されていません (BC は、当面の間、下位互換性オプションとしてシステムプロパティ -Dorg.bouncycastle.rsa.allow_pkcs15_enc=true を提供しています)。RSA-OAEP および RSA-OAEP-256 は、以前と同様に引き続き利用可能です。

その他の制限

SAML を動作させるには、XMLDSig セキュリティプロバイダーがセキュリティプロバイダーで利用可能であることを確認してください。Kerberos を動作させるには、SunJGSS セキュリティプロバイダーが利用可能であることを確認してください。FIPS 対応の RHEL 9 の OpenJDK 21 では、XMLDSig セキュリティプロバイダーは java.security でデフォルトで有効になっている可能性があり、最新の OpenJDK 17 にも当てはまります。しかし、古い OpenJDK 17 では、デフォルトで有効になっていない場合があり、これは SAML が事実上機能しないことを意味します。

SAML を動作させるには、JAVA_HOME/conf/security/java.security の fips プロバイダーリストにプロバイダーを手動で追加できます。たとえば、FIPS セキュリティプロバイダーでまだ利用可能でない場合は、次のような行を追加します。

fips.provider.7=XMLDSig

このセキュリティプロバイダーを追加すると、うまく動作するはずです。実際、これは FIPS 準拠であり、OpenJDK 21 および OpenJDK 17 の新しいバージョンではデフォルトですでに追加されています。詳細については、bugzilla を参照してください。

JAVA_HOME/conf/security/java.security を見て、ここで構成されているすべてのプロバイダーを確認し、番号が一致していることを確認することをお勧めします。言い換えれば、fips.provider.7 は、このファイルに fips.provider.N のようなプレフィックスで構成されたプロバイダーがすでに 6 つあることを前提としています。

java 自体の中の java.security ファイルを編集したくない場合は、カスタム java セキュリティファイル (たとえば kc.java.security という名前) を作成し、XMLDSig プロバイダーを追加するための上記の単一のプロパティのみをそのファイルに追加できます。次に、このプロパティファイルを添付して Keycloak サーバーを起動します。

-Djava.security.properties=/location/to/your/file/kc.java.security

Kerberos/SPNEGO の場合、セキュリティプロバイダー SunJGSS はまだ完全に FIPS 準拠ではありません。したがって、FIPS 準拠にしたい場合は、セキュリティプロバイダーのリストに追加することはお勧めしません。KERBEROS 機能は、FIPS プラットフォームで実行され、セキュリティプロバイダーが利用できない場合、Keycloak でデフォルトで無効になっています。詳細については、bugzilla を参照してください。

アルゴリズム EdDSA は FIPS モードでは使用できません。現在の BCFIPS プロバイダーは Ed25519 および Ed448 曲線 をサポートしていますが、結果のキーはそれらを管理するための標準 JDK インターフェース (EdECKeyEdECPublicKeyEdECPrivateKey、…) を実装しておらず、Keycloak は署名にそれらを使用できません。

FIPS ホストで CLI を実行する

クライアント登録 CLI (kcreg.sh|bat スクリプト) または Admin CLI (kcadm.sh|bat スクリプト) を実行する場合は、CLI もプレーンな BouncyCastle 依存関係の代わりに BouncyCastle FIPS 依存関係を使用する必要があります。これを実現するには、jar を CLI ライブラリフォルダにコピーするだけで十分です。CLI ツールは、対応する BCFIPS jar が存在することを検出すると (使用されるバージョンについては上記を参照)、プレーンな BC の代わりに BCFIPS 依存関係を自動的に使用します。たとえば、CLI を実行する前に、次のようなコマンドを使用します。

cp $KEYCLOAK_HOME/providers/bc-fips-*.jar $KEYCLOAK_HOME/bin/client/lib/
cp $KEYCLOAK_HOME/providers/bctls-fips-*.jar $KEYCLOAK_HOME/bin/client/lib/
cp $KEYCLOAK_HOME/providers/bcutil-fips-*.jar $KEYCLOAK_HOME/bin/client/lib/
CLI で BCFKS トラストストア/キーストアを使用しようとすると、このトラストストアがデフォルトの java キーストアタイプではないため、問題が発生する可能性があります。java セキュリティプロパティでデフォルトとして指定すると良い場合があります。たとえば、kcadm|kcreg クライアントで操作を行う前に、unix ベースのシステムでこのコマンドを実行します。
echo "keystore.type=bcfks
fips.keystore.type=bcfks" > /tmp/kcadm.java.security
export KC_OPTS="-Djava.security.properties=/tmp/kcadm.java.security"

コンテナ内の FIPS モードの Keycloak サーバー

FIPS モードの Keycloak をコンテナ内で実行したい場合は、「ホスト」も FIPS モードを使用している必要があります。コンテナは、親ホストから FIPS モードを「継承」します。詳細については、RHEL ドキュメントの このセクション を参照してください。

Keycloak コンテナイメージは、FIPS モードのホストから実行されると、自動的に FIPS モードになります。ただし、Keycloak コンテナも、起動時に BCFIPS jar (BC jar の代わりに) と適切なオプションを使用していることを確認してください。

これに関して、コンテナで Keycloak を実行する で説明されているように、独自のコンテナイメージを構築し、BCFIPS などを使用するように調整するのが最善です。

たとえば、現在のディレクトリに files というサブディレクトリを作成し、次を追加できます。

  • 上記で説明した BC FIPS jar ファイル

  • カスタムキーストアファイル - たとえば keycloak-fips.keystore.bcfks という名前

  • SAML 用のプロバイダーが追加されたセキュリティファイル kc.java.security (OpenJDK 21 以降または新しい OpenJDK 17 では不要)

次に、現在のディレクトリに次のような Containerfile を作成します。

Containerfile
FROM quay.io/keycloak/keycloak:latest as builder

ADD files /tmp/files/

WORKDIR /opt/keycloak
RUN cp /tmp/files/*.jar /opt/keycloak/providers/
RUN cp /tmp/files/keycloak-fips.keystore.* /opt/keycloak/conf/server.keystore
RUN cp /tmp/files/kc.java.security /opt/keycloak/conf/

RUN /opt/keycloak/bin/kc.sh build --features=fips --fips-mode=strict

FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/

ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

次に、最適化された Docker イメージとして FIPS を構築し、コンテナで Keycloak を実行する で説明されているように起動します。これらの手順では、イメージを起動する際に、上記で説明した引数を使用する必要があります。

非 FIPS 環境からの移行

以前に非 FIPS 環境で Keycloak を使用していた場合、データを含めて FIPS 環境に移行できます。ただし、前のセクションで述べたように、制限事項と考慮事項があります。つまり、

  • Keycloak 25 以降では、パスワードハッシュのデフォルトアルゴリズムは argon2 です。ただし、このアルゴリズムは FIPS 140-2 ではサポートされていません。これは、ユーザーが argon2 でパスワードをハッシュした場合、FIPS 環境に切り替えた後、ログインできなくなることを意味します。FIPS 環境への移行を計画している場合は、最初から (ユーザーが作成される前に) レルムのパスワードポリシーを設定し、デフォルトのアルゴリズムを FIPS 準拠の pbkdf2-sha512 などにオーバーライドすることを検討してください。この戦略は、FIPS 環境への移行をスムーズにするのに役立ちます。そうでない場合、ユーザーがすでに argon2 パスワードを使用している場合は、FIPS 環境への移行後にパスワードをリセットするようにユーザーに依頼するだけです。「パスワードを忘れた場合」を使用するか、すべてのユーザーにパスワードリセットのメールを送信するように依頼します。

  • キーストアに依存するすべての Keycloak 機能が、サポートされているキーストアタイプのみを使用していることを確認してください。これは、厳密モードまたは非厳密モードのどちらが使用されているかによって異なります。

  • Kerberos 認証が機能しない場合があります。認証フローで Kerberos 認証器を使用している場合、FIPS 環境に移行すると、この認証器は自動的に DISABLED に切り替えられます。FIPS 環境に切り替える前に、レルムから Kerberos ユーザー ストレージ プロバイダーを削除し、LDAP プロバイダーで Kerberos 関連の機能を無効にすることをお勧めします。

上記の要件に加えて、FIPS 厳密モードに切り替える前に、これを再確認してください。

  • キー (たとえば、レルムキーまたはクライアントキー) に依存するすべての Keycloak 機能が、少なくとも 2048 ビットの RSA 鍵を使用していることを確認してください。

  • Signed JWT with Client Secret に依存するクライアントが、少なくとも 14 文字長のシークレット (理想的には生成されたシークレット) を使用していることを確認してください。

  • 前述のパスワード長の制限。ユーザーのパスワードが短い場合は、前述のように、PBKDF2 プロバイダーの最大パディング長を 14 に設定してサーバーを起動してください。このオプションを避けたい場合は、たとえば、新しい環境での最初の認証中に、すべてのユーザーにパスワードのリセット (たとえば、パスワードを忘れた場合 リンクを使用) を依頼できます。

非 FIPS システムでの Keycloak FIPS モード

Keycloak は、FIPS 対応の RHEL 8 システムおよび ubi8 イメージでサポートおよびテストされています。RHEL 9 (および ubi9 イメージ) でもサポートされています。非 RHEL 互換プラットフォームまたは非 FIPS 対応プラットフォームで実行する場合、FIPS 準拠は厳密に保証できず、公式にはサポートできません。

それでもそのようなシステムで Keycloak を実行する必要がある場合は、少なくとも java.security ファイルで構成されたセキュリティプロバイダーを更新できます。この更新は FIPS 準拠にはなりませんが、少なくともセットアップはそれに近づきます。これは、前に説明したように、オーバーライドされたセキュリティプロバイダーのリストのみを含むカスタムセキュリティファイルを提供することで実行できます。推奨されるプロバイダーのリストについては、OpenJDK 21 ドキュメント を参照してください。

起動時に Keycloak サーバーログを確認して、正しいセキュリティプロバイダーが使用されているかどうかを確認できます。Keycloak の起動コマンドで前に説明したように、暗号関連の Keycloak パッケージに対して TRACE ロギングを有効にする必要があります。

このページについて