原文はこちら。
The original article was written by Sean Mullan (Java Security Tech Lead, Oracle).
https://seanjmullan.org/blog/2021/09/14/jdk17
JDK 17が2021年9月14日(PST)にリリースされました。以前のエントリのように、今回のリリースで最も興味深く有用と思われるセキュリティ機能の強化点をまとめました。また、それらを適切なカテゴリー(暗号、TLSなど)に分類したので、それぞれの分野で何が変わったのかを簡単に見つけることができるはずです。JDK 17のリリースノートにも、これらの強化点やその他の強化点についての詳細が記載されています。
JDK 17
https://openjdk.java.net/projects/jdk/17/
Sean Mullanのブログ
https://seanjmullan.org/blog/
JDK 17 Release Notes
https://jdk.java.net/17/release-notes
JDK 17でおそらく最も重要なセキュリティに関する変更は、JEP 411(Deprecate the Security Manager for Removal)でしょう。数多くのSecurity ManagerのAPIの廃止ならびにSecurity Managerを使っているアプリケーションに対して実行時の警告を追加することにより、JDK 17でこのプロセスがスタートしています。詳細はSecurity Managerの章で後述します。
JEP 411: Deprecate the Security Manager for Removal
https://openjdk.java.net/jeps/411
また、その他の3個の重要なJDK 17の機能があります。これらはセキュリティライブラリの分野には含まれていませんが、以下のようなセキュリティ上のメリットを有しています。
JEP 403: Strongly Encapsulate JDK Internals
JEP 403で、JDK 17は引き続き強力なJDK内部のカプセル化を強化するため、強力なカプセル化を緩めるためのコマンドラインスイッチを無効にしました。代わりに、--add-opens
または --add-exports
コマンドライン・オプションを使用して、必要に応じてパッケージを個別にopen/exportする必要があります。
JEP 409: Sealed Classes
Sealed class(シールクラス)を使うと、特定のクラスを拡張したり実装したりすることが許されるクラスを制限できます。これは、クラスの不正な実装を防ぐために使用できるので、明らかにセキュリティ上の利点があります。
JEP 415: Context-Specific Deserialization Filters
デシリアライゼーション・フィルターはJDK 9で導入されました。
JEP 290: Filter Incoming Serialization Data
https://openjdk.java.net/jeps/290
これにより、アプリケーションやライブラリが、受信した直列化されたストリームをデシリアライズする前に検証できます。この検証は、セキュリティ・プロパティを使って静的にも、またはObjectInputStream
に適用される新しいObjectInputFilter
APIを使って動的にも実施できます。JEP 415では、オブジェクト・ストリームに応じて異なるフィルタを適用するために使用できるフィルタ・ファクトリを導入することで、この機能を改善しています。
Table of Contents
Crypto
KW (Key Wrap) モードに加え、KWP (Key Wrap With Padding) もサポート (JDK-8248268)
SunJCE
プロバイダがAES Key Wrap With Padding (KWP) モードをサポートしました。また、AES Key Wrapモード(KW)が強化され、(ラップに加えて)鍵の暗号化、カスタムIV (Initialization vector) やパディングスキームをサポートしています。これらの標準モードは、暗号鍵を保護するために設計されており、NIST SP 800-38Fで定義されています。
SP 800-38F : Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping
https://csrc.nist.gov/publications/detail/sp/800-38f/final
これらのモードをJavaアプリケーションでjavax.crypto.Cipher
APIと共に使用して、アルゴリズム変換 AES/KWP/NoPadding
、AES/KW/PKCS5Padding
、またはAES/KW/NoPadding
を指定して使用します。そのかわりに、CipherアルゴリズムとしてAESWrap
(NoPaddingのKWモードと等価)、もしくはAESWrapPad
(NoPaddingのKWPモードと等価)を指定できます。
JCEではPKCS#1でRSA秘密鍵を扱うクラスを提供しない (JDK-8023980)
KeyFactory
のRSA
実装は(PKCS#8エンコーディングに加え)PKCS#1エンコーディングから秘密鍵および公開鍵を生成できるようになりました。
SunPKCS11プロバイダーにChaCha20とPoly1305のサポートを追加 (JDK-8255410)
基礎となるPKCS#11実装がChaCha20とPoly1305ストリーム暗号をサポートしている場合、SunPKCS11プロバイダーがChaCha20とPoly1305ストリーム暗号をサポートするようになりました。
PKI
RFC 8954(Online Certificate Status Protocol (OCSP) Nonce Extension)のサポートを追加 (JDK-8256895)
PKIX の実装に OCSP Nonce Extension のサポートが追加されました。
Online Certificate Status Protocol (OCSP) Nonce Extension
https://datatracker.ietf.org/doc/rfc8954/
Nonce Extensionは、証明書に対する以前の良好なOCSPResponseが期限切れになっていないにもかかわらず、証明書のステータスが変更され(例えば失効した、とか)、以前の良好な OCSPResponse が再生できるというリプレイ攻撃を防ぐのに役立ちます。
互換性の理由から、この拡張機能はデフォルトでは有効になっていませんが、jdk.security.certpath.ocspNonce
システムプロパティをtrueに設定することで有効にできます。有効になっていない場合、デフォルトのJDKの実装では、RFC 5019で規定されている時間ベースのアプローチが使用されます。
Replay Attacks
https://datatracker.ietf.org/doc/html/rfc5019#section-7.1
JavaでOCSPのGET呼出しのサポートが必要 (JDK-8179503)
JDKのPKIX実装では、リクエストが255バイトを下回る場合、(POSTではなく)HTTP GETを使ってOCSPリクエストを送信するようになりました。GETを使うことでリクエストをキャッシュでき、結果パフォーマンスが改善します。
新たにHARICAのroot CA証明書を追加 (JDK-8256421)
HARICA が所有する 2 つの新しいルート CA 証明書がcacerts
キーストアに追加されました。
Harica
https://www.harica.gr/
HARICA Root CA 2015
このルート証明書は、以下の識別名を持ちます。
CN=Hellenic Academic and Research Institutions RootCA 2015, O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR
HARICA ECC Root CA 2015
このルート証明書は、以下の識別名を持ちます。
CN=Hellenic Academic and Research Institutions ECC RootCA 2015, O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR
これらのルート証明書はOracle JDK 16.0.1、11.0.11、8u291、7u301のcacerts
キーストアにも追加されています。
TLS
システムプロパティで設定可能な拡張機能 (JDK-8217633)
TLSの相互運用性の問題は、実装がサポートしていないTLS拡張を適切に処理しない場合に発生することがあります。このような問題を回避するために、2つの新しいシステム・プロパティが導入され、TLS接続の確立時に有効化されない(つまり無効な)拡張 (extension) をカスタマイズできるようになりました。
このシステムプロパティは、クライアント (jdk.tls.client.disableExtensions
) またはサーバー (jdk.tls.server.disableExtensions
) に適用されます。プロパティの値は、標準的なTLS拡張機能名のコンマ区切りのリストです。
Transport Layer Security (TLS) Extensions
https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
例えば、以下のようになります。
java -Djdk.tls.client.disabledExtensions="status_request,signature_algorithms_cert" ...
Kerberos
Kerberosにおける3DESとRC4の非推奨化 (JDK-8139348)
3DESおよびRC4のKerberos暗号化タイプは、現在デフォルトで無効になっています。3DESとRC4はどちらも弱い暗号化アルゴリズムであり、使用すべきではありません。Kerberosの3DESとRC4の暗号化タイプは、RFC 8429で公式に非推奨とされています。
Deprecate Triple-DES (3DES) and RC4 in Kerberos
https://datatracker.ietf.org/doc/html/rfc8429
デフォルトではdes3-hmac-sha1
とrc4-hmac
の暗号化タイプは無効になっていますが、krb5.conf
設定ファイルでallow_weak_crypto
プロパティをtrueに設定することで、自己責任で再び有効にすることができます。ただし、des-cbc-crc
やdes-cbc-md5
など、すでに無効になっている他の弱い暗号化タイプも再び有効になることに注意してください。もしくは、default_tkt_enctypes
、default_tgs_enctypes
、perferred_enctypes
プロパティを、許可されている暗号化タイプに設定してください。
XML Signature
RSASSA-PSS
パラメター用SignatureMethodParameterSpec
サブクラスの追加 (JDK-8259575)
XML Signature API に javax.xml.crypto.dsig.spec.RSAPSSParameterSpec という名前の新しいクラスが追加され、RSASSA-PSS 署名アルゴリズムのパラメータの指定に使用できるようになりました。また、署名アルゴリズム(RSA_PSS)の新しいString定数が定義されています。
新しいAPIでは、java.security.spec.PSSParameterSpec
を入力パラメータとして使用します。
Class RSAPSSParameterSpec
https://docs.oracle.com/en/java/javase/17/docs/api/java.xml.crypto/javax/xml/crypto/dsig/spec/RSAPSSParameterSpec.html
RSA_PSS(定数文字列)
https://docs.oracle.com/en/java/javase/17/docs/api/java.xml.crypto/javax/xml/crypto/dsig/SignatureMethod.html#RSA_PSS
SHA-1 XML署名の無効化 (JDK-8259709)
SHA-1 ベースのダイジェストまたは署名アルゴリズムを含むXML署名は、デフォルトで無効になりました。SHA-1 は弱いダイジェストアルゴリズムであり、ダイジェストおよび署名アルゴリズムとしては推奨されなくなりました。この制約に違反したXML署名の検証は失敗します。
自己責任の下、必要に応じて、java.security
設定ファイルに定義されているjdk.xml.dsig.sureValidationPolicy
セキュリティプロパティを変更またはオーバーライドすることで、SHA-1を再び有効にすることができます。
XML署名のセキュア検証モードがデフォルトで有効化 (JDK-8259801)
XML Signatureのセキュア検証モードがデフォルトで有効になりました。以前はアプリケーションがjavax.xml.crypto.XMLCryptoContext.setProperty()
メソッドを使ってorg.jcp.xml.dsig.secureValidation
プロパティをtrueにするか、SecurityManagerを有効にしてコードを実行することにより、このモードを明示的に有効にする必要がありました。潜在的に敵対的なコンテンツが含まれていたり、弱いアルゴリズムが使われていたり、DoSを引き起こす可能性のある構成要素が含まれていたりするXML署名に対し、このセキュア検証モードが追加の保護を提供します。現在このモードには以下の制約事項があります。
- XSLT変換の使用不可
- SignedInfo または Manifest Reference 要素数は30 以下
- Reference変換の数は5以下
- MD5 署名または MAC アルゴリズムの使用を禁じます。
- SHA-1署名アルゴリズムの使用不可
- 署名の折り返し攻撃を防ぐために、Reference IDが一意であることを確保しなければならない
- http、https、またはfile型の参照URIの使用不可
- RetrievalMethod要素は他のRetrieveralMethod要素の参照不可
- 1024ビット以下のRSAまたはDSA鍵,および224ビット以下のEC鍵は利用不可
このモードの詳細については、XML Signature API Overview and TutorialのXML Signature Secure Validation Modeを参照してください。
XML Signature Secure Validation Mode
https://docs.oracle.com/en/java/javase/17/security/java-xml-digital-signature-api-overview-and-tutorial.html#GUID-8618C294-3BFE-45C3-9A1E-C4629E337E68
Security Manager
削除に向けたSecurity Managerの非推奨化 (JEP 411)
JDK 17 では、Security Managerは削除に向け非推奨になりました。これには、java.lang.SecurityManager
APIと、Security Managerに関連するいくつかのAPIが含まれます。影響を受けるAPIの完全なリストについては、JEPのDeprecate APIs for removalセクションを参照してください。
Deprecate APIs for removal (JEP 411)
https://openjdk.java.net/jeps/411#Deprecate-APIs-for-removal
Security Managerが廃止される理由はいくつかありますが、それらはJEPのMotivation (動機)のセクションで詳しく説明されています。
Motivation (JEP 411)
https://openjdk.java.net/jeps/411#Motivation
【注意】JDK 17ではSecurity Managerは引き続き完全にサポートされますが、Security Managerが有効になっている場合は、実行時に警告が表示されます。これにより、ユーザーや開発者に非推奨であることを警告し、将来の廃止に備えることができます。