原文はこちら。
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
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/NoPadding
、AES/KW/PKCS5Padding
、AES/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.Entry
のgetAttributes
メソッドを呼び出すしかありませんでした。エントリが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のキー管理の項を参照してください。
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.conf
のdefault_checksum
とsafe_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
(keytool
とjarsigner
の新たなオプション --version
)
--version
という新たなオプションがkeytool
とjarsigner
に加わりました。このオプションを指定すると、以下のようにツールが利用している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