セキュリティ・プロパティ・ファイル

セキュリティ・プロパティ・ファイルは、セキュリティ・プロパティの名前とその値を含むテキスト・ファイルです。これらのプロパティを設定することで、Javaセキュリティの特定の側面をカスタマイズできます。

$JAVA_HOMEにあるJDKからJavaアプリケーションを起動すると、JVMはデフォルトで、セキュリティ・プロパティを$JAVA_HOME/conf/security/java.security(マスター・セキュリティ・プロパティ・ファイルと呼ばれる)で指定された値に設定します。別のセキュリティ・プロパティ・ファイルを指定できます。「代替セキュリティ・プロパティ・ファイルの指定」を参照してください。

セキュリティ・プロパティ・ファイルで設定されるセキュリティ・プロパティは、静的に設定されます。アプリケーションのコードに値を設定することで、セキュリティ・プロパティを動的に設定できます。「セキュリティ・プロパティ・ファイルでのセキュリティ・プロパティの静的な設定」および「アプリケーション・コードでのセキュリティ・プロパティの動的な設定」を参照してください。

セキュリティ・プロパティのロギングの有効化および表示の詳細は、「セキュリティ・プロパティのトラブルシューティング」を参照してください。

セキュリティ・プロパティ設定を含むテキスト・ファイルをマスター・セキュリティ・プロパティ・ファイルまたはその他のセキュリティ・プロパティ・ファイルに含めることができます。ファイルを含めると、そのセキュリティ・プロパティ設定はすべて、その時点で定義されているかのように追加されます。「セキュリティ・プロパティ・ファイルの組込み」を参照してください。

デフォルトでは、マスター・セキュリティ・プロパティ・ファイルは、次のようなJavaの特定の側面をカスタマイズするセキュリティ・プロパティを設定します:

  • セキュリティ・プロバイダの登録: セキュリティ・プロバイダは、JavaセキュリティAPIの暗号化の側面のサブセットの具体的な実装を提供するパッケージまたはパッケージのセットです。マスター・セキュリティ・プロパティ・ファイルは、security.provider.nという形式で複数のセキュリティ・プロパティを設定します。nはプロバイダの優先順位です。優先順位とは、特定プロバイダの指定がない場合に、要求されたアルゴリズムに関して検索されるプロバイダの順位です。

    詳細は、「ステップ8.1: プロバイダの構成」を参照してください。

  • アルゴリズムの制限: 証明書パス検証、TLS、署名付きJARファイルおよびXML署名検証のための制限付きアルゴリズムおよびレガシー・アルゴリズムが対象となります。たとえば、jdk.certpath.disabledAlgorithmsおよびjdk.tls.disabledAlgorithmは、証明パス検証およびTLS/DTLSプロトコル・ネゴシエーション中に無効にするアルゴリズムをリストします。
  • Java Secure Socket Extension (JSSE): JSSEにより、セキュアなインターネット通信が可能になります。これは、JavaバージョンのTLSおよびDTLSプロトコルのフレームワークおよび実装を提供し、データ暗号化、サーバー認証、メッセージの整合性の他、オプションでクライアント認証の機能を含んでいます。関連するセキュリティ・プロパティには次のものがあります:

    • jdk.tls.keyLimits: アルゴリズムでキー・セットを使用して暗号化可能なデータ量を制限します
    • ssl.KeyManagerFactoryおよびssl.TrustManagerFactoryjavax.net.sslパッケージのデフォルトのキーおよびトラスト・マネージャ・ファクトリ・アルゴリズムを指定します

    詳細は、「JSSEのカスタマイズ」を参照してください。

  • Javaセキュリティのその他の側面: これには、デフォルトのキーストア・タイプ、SecureRandom実装の構成およびKerberosが含まれます。

代替セキュリティ・プロパティ・ファイルの指定

コマンドラインからシステム・プロパティjava.security.properties=<URL>を使用して、代替のjava.securityプロパティ・ファイルを指定できます。このプロパティ・ファイルは、マスター・セキュリティ・プロパティ・ファイルに追加されます。java.security.properties==<URL>(等号を2つ使用)でプロパティ・ファイルを指定すると、そのプロパティ・ファイルはマスター・セキュリティ・プロパティ・ファイルを完全にオーバーライドします。

セキュリティ・プロパティ・ファイルでのセキュリティ・プロパティの静的な設定

セキュリティ・プロパティ・ファイルでセキュリティ・プロパティ値を静的に設定するには、次の形式で既存の行を追加または変更します:

propertyName=propertyValue

たとえば、デフォルトのSunX509以外のキー・マネージャ・ファクトリのアルゴリズム名を指定するとします。これを実行するには、ssl.KeyManagerFactory.algorithmというセキュリティ・プロパティの値として、アルゴリズム名を指定します。たとえば、値をMyX509に設定するには、次の行を追加します:

ssl.KeyManagerFactory.algorithm=MyX509

セキュリティ・プロパティ・ファイルの行をコメント・アウトする(つまり、セキュリティ・プロパティ・ファイルからセキュリティ・プロパティを設定するときにJVMがその行を無視するようにする)には、行の先頭に番号記号(#)を挿入します。

デフォルトでは、マスター・セキュリティ・プロパティ・ファイルには、指定されたセキュリティ・プロパティを詳細に説明する多くのコメントが含まれています。これらのセキュリティ・プロパティ自体がコメント・アウトされる場合があります。コメント・アウトされたこれらのセキュリティ・プロパティには、値が指定されている場合も、値がまったく指定されていない場合もあります。

ノート:

値が設定されていないセキュリティ・プロパティは、空の文字列に設定されます。コメント・アウトされたセキュリティ・プロパティはnull値に設定されます。この場合、セキュリティ・プロパティにデフォルト値が割り当てられることがあります。マスター・セキュリティ・プロパティ・ファイルのコメントでは、セキュリティ・プロパティにデフォルト値があるかどうかを指定する必要があります。

アプリケーション・コードでのセキュリティ・プロパティの動的な設定

アプリケーション・コードでセキュリティ・プロパティを動的に設定するには、java.security.Security.setPropertyメソッドをコールします:

Security.setProperty("propertyName," "propertyValue");

たとえば、キー・マネージャ・ファクトリのアルゴリズム名を指定する、前の例に対応したsetProperty()メソッドの呼出しでは:

Security.setProperty("ssl.KeyManagerFactory.algorithm", "MyX509");

ノート:

一部のセキュリティ・プロパティは、java.security.Securityクラスの初期化時にセキュリティ・プロパティ・ファイルから読み取られてキャッシュされている場合、動的に設定できません。コードでこれを試みても例外はスローされません。

セキュリティ・プロパティのトラブルシューティング

コマンドライン・オプション-Djava.security.debug=propertiesを指定して、セキュリティ・プロパティのロギングを有効にします。propertiesという接頭辞が付いたメッセージには、すべてのセキュリティ・プロパティの最終値と、includeディレクティブの処理方法に関する情報が含まれます。「java.security.debugシステム・プロパティ」を参照してください。

コマンドライン・オプション-XshowSettings:securityは、JDKで有効なセキュリティ設定の概要を出力します。「java -XshowSettings:securityオプション」を参照してください。

Java Flight Recorder (JFR)イベントjdk.InitialSecurityPropertyを使用して、実行中のJDKのセキュリティ・プロパティの初期値を取得できます。

セキュリティ・プロパティ・ファイルの組込み

セキュリティ・プロパティ・ファイルを別のセキュリティ・プロパティ・ファイルに含めるには、includeディレクティブを使用します。この機能により、セキュリティ・プロパティを複数のファイルに定義でき、複数のJDKにまたがるセキュリティ・プロファイルの集中管理が容易になります。

たとえば、LinuxおよびmacOSで、別のセキュリティ・プロパティ・ファイルにセキュリティ・プロパティ・ファイル/usr/lib/jvm/jdk-24/conf/security/extra.securityを含めるには、次のincludeディレクティブを追加します:

include /usr/lib/jvm/jdk-24/conf/security/extra.security

Windowsで、セキュリティ・プロパティ・ファイルC:\Java\jdk-24\conf\security\extra.securityを別のセキュリティ・プロパティ・ファイルに含めるには、次のincludeディレクティブを追加します:

include C:\\Java\\jdk-24\\conf\\security\\extra.security

includeディレクティブ内のファイル・システム・パスは、前述の例のように絶対パスでも相対パスでもかまいません。相対パスである場合は、includeディレクティブを含むファイルの場所がベースとして使用されます。includeディレクティブがURLストリーム内にある場合、相対パスは使用できません。たとえば、Javaアプリケーションの起動時にコマンドラインで次のオプションを指定すると、セキュリティ・プロパティ・ファイルextra.java.securityに相対パスを指定するincludeディレクティブを含めることはできません:

-Djava.security.properties=https://example.com/extra.java.security

LinuxおよびmacOSでは、スラッシュ(/)がサポートされています。

Windowsでは、ダブル・バックスラッシュ(\\)、シングル・フォワード・スラッシュ(/)およびUNCパスがサポートされています。たとえば:

include C:\\Program Files\\Java\\jdk-24\\java.config
include C:/Program Files/Java/jdk-24/additional.java.config
include \\\\WindowsHost\\Share\\unc.path.java.config

URLファイル・パス(たとえば、file://で始まるパス)はサポートされていません。

includeディレクティブは、プロパティの展開をサポートします。これは、シェルでの変数の展開に似ています。${some.property}のような文字列がincludeディレクティブにある場合、システム・プロパティの値に展開されます。たとえば:

include ${java.home}/extra.security

これにより、${java.home}が展開され、java.homeシステム・プロパティの値が使用されます。このプロパティの値が/usr/lib/jvm/jdk-24の場合、前述の例は次のようになります:

include /usr/lib/jvm/jdk-24/conf/security/extra.security

プラットフォームに依存しないポリシー・ファイルの作成を簡単にするために、${/}という特殊な表記(${file.separator}のショートカット)も使用できます。これにより、次のようなディレクティブが可能になります:

include ${java.home}${/}extra.security

ノート:

includeディレクティブのシステム・プロパティが定義されていない場合、JVMがエラーを生成するのではなく、空の文字列に置き換えられます。

JVMは、includeディレクティブを検出すると、先行または後続の出現に関係なくただちにそれを処理します。ファイル内の位置は、「セキュリティ・プロパティ・ファイルでのincludeディレクティブの順序」で説明されているように、セキュリティ・プロパティの値に影響することがあります。ただし、includeディレクティブは相互に干渉せず、JVMは常にディレクティブを処理します。一方、セキュリティ・プロパティの後半で定義されたセキュリティ・プロパティまたは後続のincludeによって取り込まれたセキュリティ・プロパティは、名前が同じ場合、それより前の定義をオーバーライドします。

ファイルを含めることができない場合、JVMはエラーを生成します。これは、ファイルを解決できないか、ファイルが存在しないか、ディレクトリであるか、JVMがファイルを読み取るための十分な権限がないか、再帰的に複数回含まれているか、またはその他の理由で発生する可能性があります。

インクルードされたセキュリティ・プロパティ・ファイルには、循環参照が発生しないかぎり、他のファイルを再帰的に含めることができます。たとえば、java.securityにセキュリティ・プロパティ・ファイルA.securityが含まれ、A.securityにセキュリティ・プロパティ・ファイルB.securityが含まれているとします。循環参照が発生するため、セキュリティ・プロパティ・ファイルB.securityA.securityを含めることはできません。

セキュリティ・プロパティ・ファイルでのincludeディレクティブの順序

includeディレクティブでセキュリティ・プロパティ・ファイルを含めると、インクルードされたファイルに定義されているプロパティは、セキュリティ・プロパティのマップに追加されるか、名前が同じ場合は既存のプロパティが置換されます。このように、includeディレクティブの効果は、プロパティ・ファイル内のその位置によって異なります。したがって、includeディレクティブの前に定義することでオーバーライド可能なセキュリティ・プロパティを指定し、includeディレクティブの後に定義することでオーバーライド不可能なセキュリティ・プロパティを指定できます。

セキュリティに関する考慮事項およびセキュリティ・プロパティ・ファイル内のincludeディレクティブ

セキュリティ・プロパティ・ファイルのレイアウトは、システム管理者がセキュリティ・プロパティが定義およびオーバーライドされた理由を明確かつ簡単に理解できるようにすることが重要です。「セキュリティ・プロパティのトラブルシューティング」で説明する方法を使用して、JDKのセキュリティ・プロパティの最終マップを確認することをお薦めします。

ノート:

セキュリティ・プロパティ・ファイルを含める場合は、信頼できるソースからのものであることを確認し、インクルードされるファイルだけでなく、ファイル・システムのルートから始まる親ディレクトリのチェーン全体に対する書込み権限もチェックすることを強くお薦めします。インクルードされたファイルを変更できるユーザーは、セキュリティ・プロパティ・ファイルを置き換えたり、セキュリティ・プロパティ値をオーバーライドする新しいファイルを追加することで、JDKのセキュリティを低下させる可能性があります。親ディレクトリのチェーン内のディレクトリの名前を変更できるユーザーは、インクルードされたファイルを不正なバージョンに偽装でき、JDKセキュリティの低下につながる可能性があります。経験則として、インクルードされたファイルとその親ディレクトリのチェーンは、そのincludeディレクティブを含むファイルと同じか、より制限的な権限を持っている必要があります。

ファイル・システム・パスでプレースホルダが使用され、「セキュリティ・プロファイル」の説明に従ってシステム・プロパティが渡される場合、入力ミスによる影響に注意する必要があります。プロパティ名に入力ミスがある場合、プレースホルダは無視されます。プロパティ値に入力ミスがある場合は、インクルードされるファイルが存在する必要があるため、エラーがスローされます。プレースホルダと引数内のシステム・プロパティに入力ミスがないか、常に確認してください。

includeディレクティブの使用例

セキュリティ・プロファイル

システム管理者は、セキュリティ強化、規制遵守、または後方互換性の維持のために、複数のJDKデプロイメントのJavaアプリケーション全体にセキュリティ・プロファイルを強制することがよくあります。これらのセキュリティ・プロファイルで指定するセキュリティ・プロパティは、個々のJDKデプロイメントで指定されるセキュリティ・プロパティに加えて指定する必要があります。多くの場合、システム管理者は、開発や本番などの環境に応じて異なるセキュリティ・プロファイルを適用する必要があります。また、セキュリティ・プロファイルを一元管理できる必要があります。

このシナリオを実装するには、個別のセキュリティ・プロパティ・ファイルを使用して複数のグローバル・セキュリティ・プロファイルを定義します。グローバル・セキュリティ・プロファイルは、各JDKデプロイメントで必要なセキュリティ・プロパティを指定します。ブリッジ・ファイルを定義し、このファイルには、デフォルトで適用されるグローバル・セキュリティ・プロファイルを指定するincludeディレクティブを含めます。このブリッジ・ファイルを各JDKデプロイメントのマスター・セキュリティ・プロパティ・ファイルに含めます。デフォルト・プロファイルを変更するには、ブリッジ・ファイルのincludeディレクティブを変更します。

ブリッジ・ファイルを介して複数のグローバル・セキュリティ・プロファイルを管理するこの概念を説明するために、次のセキュリティ・プロパティ・ファイルのレイアウトとそのincludeディレクティブについて考えてみます:

  • ディレクトリ /global/profiles
    • ファイル profile-.security(ブリッジ・ファイル):
      include profile-prod.security
    • ファイル profile-custom.security(グローバル・セキュリティ・プロファイル)
    • ファイル profile-dev.security(グローバル・セキュリティ・プロファイル)
    • ファイル profile-prod.security(グローバル・セキュリティ・プロファイル。デフォルトで適用されます)
  • JDKデプロイメントA: ディレクトリ $JAVA_HOME_DEPLOYMENT_A/conf/security
    • ファイル java.security:
      include /global/profiles/profile-${securityProfile}.security
  • JDKデプロイメントB: ディレクトリ $JAVA_HOME_DEPLOYMENT_B/conf/security
    • ファイル java.security:
      include /global/profiles/profile-${securityProfile}.security

このレイアウト例では、profile-.securityは、デフォルトで適用されるグローバル・セキュリティ・プロファイルprofile-prod.securityを指定するincludeディレクティブを含むブリッジ・ファイルです。システム管理者は、ブリッジ・ファイルのincludeディレクティブを変更し、ディレクトリ/global/profilesのいずれかのポリシー(profile-custom.securityprofile-dev.securityまたはprofile-prod.security)を参照することで、デフォルトのグローバル・セキュリティ・プロファイルを変更できます。

アプリケーションで、デフォルトで適用されるセキュリティ・プロファイルとは異なるセキュリティ・プロファイルが必要になる場合があります。この例では、JDKデプロイメントAおよびBのincludeディレクティブは、プレースホルダ接尾辞securityProfileを使用します。システム・プロパティsecurityProfileが未定義の場合、このプレースホルダは空の文字列に置き換えられ、JDKデプロイメントAおよびBはブリッジ・ファイルprofile-.securityを使用します。システム・プロパティsecurityProfileが、使用可能な値(customdevまたはprod)のいずれかに設定されている場合、それぞれのグローバル・セキュリティ・プロファイルが選択されます。たとえば、-DsecurityProfile=devコマンドライン・オプションを使用してJavaアプリケーションを起動すると、デフォルトで適用されるプロファイルに関係なく、profile-dev.securityグローバル・セキュリティ・プロファイルがJDKデプロイメントAとBの両方に適用されます。

profile-.securityファイルが存在しないレイアウトでは、デフォルトの選択は行われず、securityProfileの定義が強制的に行われます。

ノート:

セキュリティ・プロパティは、java.security.Securityクラスの初期化時に処理されます。この時点より後にプレースホルダのシステム・プロパティをプログラムで設定(java.lang.System.setProperty(String key, String value)メソッドをコール)してグローバル・セキュリティ・プロファイルを指定しても、効果はありません。

この例を拡張して、profile-.24.securityおよびprofile-prod.24.securityという名前のセキュリティ・プロパティ・ファイルを作成することで、JDKリリースに固有のセキュリティ・プロファイルを含めることができます。この場合、JDK 24java.securityセキュリティ・プロパティ・ファイルには、現在のグローバル・プロファイルに加えて、グローバル・ブリッジ・ファイルとリリース固有のブリッジ・ファイルの両方を含める必要があります。リリース固有のプロファイルを持つことは、セキュリティ・プロパティのマップがすべてのJDKリリースで同じではない場合に役立ちます。

JDKでは、厳選されたセキュリティ・プロファイルを提供することも、組織に特定の構造を優先することもありません。プロファイルを常に更新し、可能な場合は常にセキュアなデフォルトを選択することが重要です。また、セキュリティ・プロパティの可用性に関して、プロファイルが各JDKリリースにどのように適用されるかを分析することをお薦めします。