JDK 18 Security Enhancements

原文はこちら。
The original article was written by Sean Mullan (Java Security Tech Lead, Oracle).
https://seanjmullan.org/blog/2022/03/23/jdk18

2022年3月22日にJDK18がリリースされました。

JDK 18
https://openjdk.java.net/projects/jdk/18/

以前のブログと同様、今回のリリースで最も興味深く、有用だと思われるセキュリティ強化点をリストアップしてみました。また、それらを適切なカテゴリ(暗号、PKIなど)に分類し、各領域で何が変わったかを簡単に見つけられるようにしました。JDK 18のリリースノートには、これらの機能強化やその他の機能強化に関する詳細も記載されています。

Sean Mullan’s Blog
https://seanjmullan.org/blog/
JDK 18 Release Notes
https://jdk.java.net/18/release-notes

このリリースのハイライトは、Javaプラットフォームのデフォルトのセキュリティを強化するさらなる改善、新しい暗号アルゴリズムのサポート、および非推奨のセキュリティマネージャAPIに依存しない新しい代替JAAS APIが含まれています。これらとその他の強化点の詳細については、以下を参照してください。

また、暗号、TLS、JAAS/Kerberosの各コンポーネントにおいて、いくつかの性能向上が図られています。詳細は、JDK-8270317、JDK-8276660、JDK-8273299、JDK-8268427、JDK-8267125、および JDK-8273026 を参照してください。

[JDK-8270317] Large Allocation in CipherSuite
https://bugs.openjdk.java.net/browse/JDK-8270317
[JDK-8276660] Scalability bottleneck in java.security.Provider.getService()
https://bugs.openjdk.java.net/browse/JDK-8276660
[JDK-8273299] Unnecessary Vector usage in java.security.jgss
https://bugs.openjdk.java.net/browse/JDK-8273299
[JDK-8268427] Improve AlgorithmConstraints:checkAlgorithm performance
https://bugs.openjdk.java.net/browse/JDK-8268427
[JDK-8267125] AES Galois CounterMode (GCM) interleaved implementation using AVX512 + VAES instructions
https://bugs.openjdk.java.net/browse/JDK-8267125
[JDK-8273026] Slow LoginContext.login() on multi threading application
https://bugs.openjdk.java.net/browse/JDK-8273026

また、セキュリティ・ライブラリの領域には含まれませんが、ぜひとも触れておきたいJDK 18の重要な機能がもう1つあります。

JEP 421: Deprecate Finalization for Removal
https://openjdk.java.net/jeps/421

この JEP は、将来のリリースで削除するためにfinalizationを非推奨としています。ファイナライザーは様々なセキュリティ問題を引き起こす可能性があり、使用する際には特別な注意が必要です。より堅牢な代替品やテクニックはすでに利用可能であり、このJEPに記載されています。

Table of Contents

  1. Crypto
  2. PKI
  3. Kerberos
  4. Security Manager
  5. Tools
  6. Signed JARs

Crypto

PKCS#11 support for AES Key Wrap and AES Key Wrap With Padding (KWP) modes
(PKCS#11 の AES Key Wrap および AES Key Wrap With Padding (KWP) モードへの対応)

SunPKCS11プロバイダーは、基盤となるPKCS11ネイティブライブラリでサポートされている場合にAES Key WrapとAES Key Wrap With Padding (KWP) 暗号モードをサポートするようになりました。

これらの標準モードは暗号鍵を保護するために設計され、NIST SP 800-38Fで定められています。

NIST SP 800-38F
Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping
https://csrc.nist.gov/publications/detail/sp/800-38f/final

この機能拡張は、SunJCEプロバイダーにこれらのモードのサポートを追加し改善した(JDK-8248268)、JDK 17の機能拡張を基にしています。

[JDK-8248268] Support KWP in addition to KW
https://bugs.openjdk.java.net/browse/JDK-8248268

これらのモードは、javax.crypto.Cipher APIをAES/KW/NoPaddingAES/KW/PKCS5PaddingAES/KWP/NoPaddingというアルゴリズム変換 と組み合わせてJavaアプリケーションで利用します。JCEアルゴリズムのPKCS11メカニズムとのマッピングは以下の通りです。

  • AES/KW/NoPadding Cipher => CKM_AES_KEY_WRAP
  • AES/KW/PKCS5Padding Cipher => CKM_AES_KEY_WRAP_PAD
  • AES/KWP/NoPadding Cipher => CKM_AES_KEY_WRAP_KWP

JDKにおけるPKCS#11サポートに関する詳細は、以下のドキュメント(PKCS#11 Reference Guide)をご覧ください。

PKCS#11 Reference Guide
https://docs.oracle.com/en/java/javase/18/security/pkcs11-reference-guide1.html

Issue: [JDK-8264849] Add KW and KWP support to PKCS11 provider
https://bugs.openjdk.java.net/browse/JDK-8264849

New KeyStore::getAttributes() API

java.security.KeyStore APIにgetAttributes(String alias)メソッドが新規追加されました。

KeyStore::getAttributes()
https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/security/KeyStore.html#getAttributes(java.lang.String)

このメソッドは、KeyStoreのエイリアスまたはエントリに関連付けられた属性のセットを返します。この変更までは、エントリーの属性を取得するには、KeyStore.EntrygetAttributesメソッドを呼び出すしかありませんでした。エントリがPrivateKeyEntryの場合、アプリケーションは、エントリに関連付けられた属性が保護されていなくても、エントリのロックを解除するために適切なパスワードを提供する必要がありましたが、この新しいAPIでは、この問題を回避することができます。

また、プロバイダーが実装できるように、対応するengineGetAttributes(String alias)メソッドが KeyStoreSpiクラスに追加されました。

KeyStoreSpi::engineGetAttributes
https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/security/KeyStoreSpi.html#engineGetAttributes(java.lang.String)

プロバイダーがオーバーライドしなければ、KeyStore::getAttributesメソッドは空のセットを返します。サードパーティプロバイダーは、JDK 18のサポートを追加する際に、このAPIのサポートを追加する必要があります。

KeyStoreの詳細については、JCA Reference Guideのキー管理の項を参照してください。

Key Management
https://docs.oracle.com/en/java/javase/18/security/java-cryptography-architecture-jca-reference-guide.html#GUID-AB51DEFD-5238-4F96-967F-082F6D34FBEA

Issue: [JDK-8225181] KeyStore should have a getAttributes method
https://bugs.openjdk.java.net/browse/JDK-8225181

A passwordless PKCS12 keystore is now easier to create
(パスワードレスPKCS12キーストアの作成が簡単に)

パスワードレスキーストア(キーのロック解除にパスワード不要なキーストア)は、キーストアをセキュアな場所に保存し、X.509公開証明書のような機密性のない情報のみを保存することを目的としている場合に有用です。パスワードレスPKCS12キーストアを使うと、証明書は暗号化されません。そして、整合性チェックも不要ゆえにMacは適用されません。

この変更までは、パスワードレスPKCS12キーストアの作成は困難であり、様々なセキュリティプロパティを設定する必要がありましたが、JDK 18からはKeyStore::store(outStream, password) API にnullパスワードを指定するだけで、パスワードレスPKCS12キーストアを作成できるようになりました。その後、KeyStore::load() APIで、Null(または任意の)パスワードを指定して、キーストアをロードできます。

Issue: [JDK-8231107] Allow store password to be null when saving a PKCS12 KeyStore
https://bugs.openjdk.java.net/browse/JDK-8231107

PKI

The cacerts keystore is now in PKCS12 format

JDKに同梱されているルートCA証明書を保持するcacertsキーストアは、非標準のJKSフォーマットから標準のPKCS12フォーマットに変換されました。

この変更にはいくつかの利点があります。cacertsを旧式のJKSフォーマットから切り離すことができます。また、cacertをパスワードレスキーストアに対応したPKCS12形式に移行します。つまり、機密情報を保存するつもりがなければ、デフォルトのパスワード “changeit” を指定 (あるいは変更) する必要がなくなるということです。

パスワードレスキーストアの詳細については、Cryptoのセクションを参照してください。

Issue: [JDK-8275252] Migrate cacerts from JKS to password-less PKCS12
https://bugs.openjdk.java.net/browse/JDK-8275252

OCSP responses support for RSASSA-PSS

RSASSA-PSS署名アルゴリズムを使って署名されたOCSPレスポンスがサポートされるようになりました。 signature algorithm are now supported.Issue: JDK-8274471

Issue: [JDK-8274471] Add support for RSASSA-PSS in OCSP Response
https://bugs.openjdk.java.net/browse/JDK-8274471

Removal of Google’s GlobalSign Root Certificate
(GoogleのGlobalSignルート証明書の削除)

“GlobalSign” ルートCA証明書の期限が切れ、cacertsキーストアから削除されました。このルート証明書はGoogleが所有しており、以下のDistinguished Nameを持ちます。

Certificate Search
https://crt.sh/?q=14

CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2

このルート証明書はOracle JDKの17.0.2、11.0.14、8u321、7u331のcacertsキーストアからも削除されています。

Issue: [JDK-8225083] Remove Google certificate that is expiring in December 2021
https://bugs.openjdk.java.net/browse/JDK-8225083

Removal of IdenTrust Root Certificate
(IdenTrustのルート証明書の削除)

“DST Root CA X3” ルートCA証明書の期限が切れ、cacertsキーストアから削除されました。このルート証明書はIdenTrustが所有しており、以下のDistinguished Nameを持ちます。

Certificate Search
https://crt.sh/?id=8395

CN=DST Root CA X3, O=Digital Signature Trust Co.

このルート証明書はOracle JDKの17.0.2、11.0.14、8u321、7u331のcacertsキーストアからも削除されています。

Issue: [JDK-8225082] Remove IdenTrust certificate that is expiring in September 2021
https://bugs.openjdk.java.net/browse/JDK-8225082

Kerberos

Weak encryption types (DES, 3DES, RC4) have been removed from the default list of Kerberos encryption types
(Kerberos暗号化タイプのデフォルトリストから弱い暗号化タイプを削除)

DES、3DES、およびRC4という暗号化タイプは、Kerberos暗号化タイプのデフォルトリストから削除されました。このリリース以前は、これらの弱い暗号化タイプはデフォルトで無効になっており、krb5.confファイルでallow_weak_cryptoプロパティをtrueに設定しないと使用できませんでしたが、一度設定すると、弱い暗号化タイプのどれでも使用できるようになっていました。この変更により、弱い暗号化タイプを使用するには、krb5.confファイルのpermitted_enctypesプロパティ(またはdefault_tkt_enctypesまたはdefault_tgt_enctypesプロパティ)に、使用したい弱いアルゴリズムを指定する必要もあります。

これらの弱い暗号化タイプを再び有効にすることは推奨されませんので、ご自身の責任で行ってください。

サポートされるkrb5.confプロパティの詳細については、Kerberos 5 GSS-API Mechanism Guideを参照してください。

The Kerberos 5 GSS-API Mechanism
https://docs.oracle.com/en/java/javase/18/security/kerberos-5-gss-api-mechanism.html

Issue: [JDK-8273670] Remove weak etypes from default krb5 etype list
https://bugs.openjdk.java.net/browse/JDK-8273670

The krb5.conf default_checksum and safe_checksum_type properties are no longer supported
(krb5.confdefault_checksumsafe_checksum_typeプロパティはサポートされなくなる)

krb5.conf設定ファイルのdefault_checksumおよびsafe_checksum_typeプロパティは、サポートされなくなりました。

TGS-REQリクエストで使用されるチェックサムタイプは、暗号化タイプから導出するため、default_checksumプロパティは不要になりました。

safe_checksum_typeプロパティは、KRB-SAFEリクエストに使用するチェックサムのタイプを指定するもので、JDKが直接使用することはありませんでした。

Issue: [JDK-8274656] Remove default_checksum and safe_checksum_type from krb5.conf
https://bugs.openjdk.java.net/browse/JDK-8274656

Security Manager

New APIs for Subject based authorization that do not depend on the Security Manager
(Security Managerに依存しないSubjectベースの認可のための新しいAPI)

JDK 17で、JEP 411に記載されている通りSecurity Managerが将来の削除のため非推奨になりました。

JEP 411: Deprecate the Security Manager for Removal
https://openjdk.java.net/jeps/411

その変更の一環で、Security Manager APIのうち、AccessControlContextのようなSecurity Manager APIが将来の削除のため非推奨になりました。利用のためにSecurity Managerをインストールする必要がないにも関わらず、Subject::doAs()Subject::getSubject()のJAAS APIはSecurity Managerに関連するAPIに依存しています。

これらのAPIは、サブジェクトを認証し、その資格情報に基づいて機密性の高い処理を実行する安全なアプリケーションを書きたい開発者にとって重要です。そこでJEP 411では、Security Manager API に依存しない代替の JAAS API を提供する計画の概要を示しました。

この代替JAAS APIがJDK 18に追加されました。Subject::callAs()Subject::doAs()の、Subject::current()Subject::getSubject()のそれぞれ代替APIです。

Subject::callAs()
https://docs.oracle.com/en/java/javase/18/docs/api/java.base/javax/security/auth/Subject.html#callAs(javax.security.auth.Subject,java.util.concurrent.Callable)
Subject::current()
https://docs.oracle.com/en/java/javase/18/docs/api/java.base/javax/security/auth/Subject.html#current()

両APIの利用方法は以前の類似していますが、よりシンプルになっています。例えば、以下のような旧APIを使うコード

Subject s1 = new Subject();
Subject.doAs(s1,
    (PrivilegedExceptionAction<Void>)() -> {
        AccessControlContext acc = 
            AccessController.getContext();
    Subject s2 = Subject.getSubject(acc);
    return null;
});

代替APIでは以下のように書き換えることができます。

Subject s1 = new Subject();
Subject.callAs(s1, () -> { 
  Subject s2 = Subject.current();
  return null;
}); 

これらの新規APIの追加に伴い、Subject::doAs()メソッドが将来の削除のために非推奨になりました。Subject::getSubject()はすでにJDK 17で将来の削除のために非推奨になっています。JAASに関する詳細はJAAS Reference Guideをご覧ください。

Java Authentication and Authorization Service (JAAS) Reference Guide
https://docs.oracle.com/en/java/javase/18/security/java-authentication-and-authorization-service-jaas-reference-guide.html

Issue: [JDK-8267108] Alternate Subject.getSubject and doAs APIs that do not depend on Security Manager APIs
https://bugs.openjdk.java.net/browse/JDK-8267108

New default for the java.security.manager system property
(システムプロパティjava.security.managerのデフォルト値の変更)

JEP 411では、JDK 18でシステムプロパティjava.security.managerのデフォルト値をallowからdisallowに変更するという発表もしていました。この変更により、Security Managerを使わないアプリケーションのパフォーマンスが向上します。

この変更の意図は、(System::setSecurityManager()を呼び出して)動的にSecurity Managerをインストールするアプリケーションは、コマンドラインで明示的にシステムプロパティjava.security.managerをallowにする必要がある、ということです。以下はその例です。

java -Djava.security.manager=allow MyApp

Issue: [JDK-8270380] Change the default value of the java.security.manager system property to disallow
https://bugs.openjdk.java.net/browse/JDK-8270380

Tools

New keytool and jarsigner --version option
(keytooljarsignerの新たなオプション --version)

--versionという新たなオプションがkeytooljarsignerに加わりました。このオプションを指定すると、以下のようにツールが利用しているJDKバージョンが表示されます。

$ keytool --version
keytool 18 
$ jarsigner --version
jarsigner 18

これらのツールの詳細については、keytoolとjarsignerの仕様書をご覧ください。

The keytool Command
https://docs.oracle.com/en/java/javase/18/docs/specs/man/keytool.html
The jarsigner Command
https://docs.oracle.com/en/java/javase/18/docs/specs/man/jarsigner.html

Issue: [JDK-8272163] Add -version option to keytool and jarsigner
https://bugs.openjdk.java.net/browse/JDK-8272163

Signed JARs

SHA-1 JARs are disabled by default
(SHA-1で署名されたJARはデフォルトで無効化)

SHA-1アルゴリズムで署名されたJARは、デフォルトで無効になりました。SHA-1はダイジェストアルゴリズムですが、その強度はますます弱くなっており、もはや電子署名に使用するべきではありません。

この変更に伴い、以前に署名されたJARとの互換性を維持することが重要な考慮事項となったため、 2019年01月01日以前のタイムスタンプを持つSHA-1署名済みJARにはこの制限が適用されません。しかし、この互換性の制約は変更される可能性があるため、より強力なアルゴリズムでSHA-1署名済みJARを再署名することが得策です。

もしJARがSHA-1で署名されていて、上記の互換性制約を満たさない場合、SHA-1署名済みJARは制限され、署名されていないかのように扱われます。これは、JARのダイジェストと署名に使われたアルゴリズム、署名者の証明書チェーン、CRLや署名済みOCSPレスポンスのような失効データにも当てはまります。JARがタイムスタンプされている場合、それはタイムスタンプダイジェストとTSAの証明書チェーンとすべての失効データにも適用されます。

この変更は、2022年後半にOracleのアップデートリリースにバックポートされる予定です。最新の状況と予定日については、Java Crypto Roadmapを確認してください。

Oracle JRE and JDK Cryptographic Roadmap
https://java.com/en/jre-jdk-cryptoroadmap.html

jarsignerツールも強化され、JAR がこれらの制限の影響を受けるかどうかをより正確に検出し、警告するようになりました。このツールを使って、あなたのJARが影響を受けるかどうかを確認することをお勧めします。以下は、制限に抵触したSHA-1署名済みJARを検証するためにjarsignerを使用した例です(ダイジェストアルゴリズムとしての SHA-1 は “(disabled)” とフラグが立ち、jarsignerが警告を発していることに注意してください)。

$ jarsigner -verify -verbose signed.jar 

          57 Tue Mar 22 14:25:08 EDT 2022 META-INF/MANIFEST.MF
         249 Tue Mar 22 14:25:08 EDT 2022 META-INF/SIGNER.SF
        2005 Tue Mar 22 14:25:08 EDT 2022 META-INF/SIGNER.RSA
 m  ?      1 Tue Mar 22 14:24:16 EDT 2022 A

  s = signature was verified 
  m = entry is listed in manifest
  k = at least one certificate was found in keystore
  ? = unsigned entry

- Signed by "CN=signer"
    Digest algorithm: SHA-1 (disabled)
    Signature algorithm: SHA256withRSA, 2048-bit key

WARNING: The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled by the security property:

  jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, SHA1 denyAfter 2019-01-01

Issue: [JDK-8269039] Disable SHA-1 Signed JARs
https://bugs.openjdk.java.net/browse/JDK-8269039

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中