JDK 26 Security Enhancements

原文はこちら。
The original article was written by Sean Mullan (Technical Lead of the Java Security Libraries Team at Oracle).
https://seanjmullan.org/blog/2026/03/16/jdk26

JDK 26が2026年3月17日にリリースされました!これまでのブログ記事と同様、今回のリリースにおける最も興味深く有用なセキュリティ機能強化を、筆者の見解としてまとめました。また、それらを適切なカテゴリ(暗号、TLSなど)に分類しており、各分野での変更点を把握しやすくなっているはずです。JDK 26のリリースノートには、これらやその他の機能強化に関する詳細が記載されています。

今回のリリースの主なハイライトには、PEM APIの2回目のプレビュー、ハイブリッド公開鍵暗号化(HPKE)のAPIサポート、およびポスト量子ML-DSAアルゴリズムに対する署名付きJARのサポートが含まれます。

JDK 26
https://openjdk.java.net/projects/jdk/26/
原著者のこれまでのブログエントリ
https://seanjmullan.org/blog/
JDK 26リリースノート
https://jdk.java.net/26/release-notes
JEP 524: PEM Encodings of Cryptographic Objects (Second Preview)
https://openjdk.org/jeps/524

Table of Contents

  1. Crypto
  2. PKI
  3. TLS
  4. XML Signature
  5. Tools

Crypto

Hybrid Public Key Encryption [JDK-8325448]

ハイブリッド公開鍵暗号化(HPKE)のサポートを追加しました。HPKEは、受信者の公開鍵を使用して任意サイズの平文を暗号化するための最新の暗号化方式です。HPKEはRFC 9180で定義されています。これは、KEM、KDF、およびAEAD(関連データ付き認証付き暗号化)の3つの異なるアルゴリズムを組み合わせて暗号文を生成します。

RFC 9180 – Hybrid Public Key Encryption
https://www.rfc-editor.org/rfc/rfc9180.html

アプリケーションでHPKEを使用するには、既存のCipherAPIと、使用するKEM、KDF、およびAEADアルゴリズムを指定する新しいHPKEParameterSpecクラスを使用します。当初、JDK 26では、従来の非PQCアルゴリズムのみをサポートしています。ただし、Post-Quantum and Post-Quantum/Traditional Hybrid Algorithms for HPKEというインターネットドラフトがRFCとして承認され次第、今後のJDKリリースでPQCアルゴリズムのサポートを追加する予定です。

Post-Quantum and Post-Quantum/Traditional Hybrid Algorithms for HPKE
https://datatracker.ietf.org/doc/draft-ietf-hpke-pq/

HPKEParameterSpecのjavadocにあるこの例は、送信者と受信者がHPKEを使用してX25519鍵ペアでメッセージを安全に交換する様子を示しています。

    // Recipient key pair generation
    KeyPairGenerator g = KeyPairGenerator.getInstance("X25519");
    KeyPair kp = g.generateKeyPair();

    // The HPKE sender cipher is initialized with the recipient's public
    // key and an HPKEParameterSpec using specified algorithm identifiers
    // and application-supplied info.
    Cipher senderCipher = Cipher.getInstance("HPKE");
    HPKEParameterSpec ps = HPKEParameterSpec.of(
                    HPKEParameterSpec.KEM_DHKEM_X25519_HKDF_SHA256,
                    HPKEParameterSpec.KDF_HKDF_SHA256,
                    HPKEParameterSpec.AEAD_AES_128_GCM)
            .withInfo(HexFormat.of().parseHex("010203040506"));
    senderCipher.init(Cipher.ENCRYPT_MODE, kp.getPublic(), ps);

    // Retrieve the key encapsulation message (from the KEM step) from
    // the sender.
    byte[] kemEncap = senderCipher.getIV();

    // The HPKE recipient cipher is initialized with its own private key,
    // an HPKEParameterSpec using the same algorithm identifiers as used by
    // the sender, and the key encapsulation message from the sender.
    Cipher recipientCipher = Cipher.getInstance("HPKE");
    HPKEParameterSpec pr = HPKEParameterSpec.of(
                    HPKEParameterSpec.KEM_DHKEM_X25519_HKDF_SHA256,
                    HPKEParameterSpec.KDF_HKDF_SHA256,
                    HPKEParameterSpec.AEAD_AES_128_GCM)
            .withInfo(HexFormat.of().parseHex("010203040506"))
            .withEncapsulation(kemEncap);
    recipientCipher.init(Cipher.DECRYPT_MODE, kp.getPrivate(), pr);

    // Encryption and decryption
    byte[] msg = "Hello World".getBytes(StandardCharsets.UTF_8);
    byte[] ct = senderCipher.doFinal(msg);
    byte[] pt = recipientCipher.doFinal(ct);

    assert Arrays.equals(msg, pt);

PKCS#12 KeyStore support for RFC 9879: Use of Password-Based Message Authentication Code 1 (PBMAC1) [JDK-8343232]

JDK の PKCS12 KeyStore実装は、完全性保護のためのより新しい PBMAC1 アルゴリズムをサポートするようになりました。PBMAC1 アルゴリズムを使用するには、java.security設定ファイル内の keystore.pkcs12.macAlgorithmプロパティを、PBMAC1 アルゴリズム(例: “PBEWithHmacSHA256”)に設定します。既存の PKCS12 キーストアファイルは、作成時に使用された整合性アルゴリズムを引き続き使用しますが、新しいキーストアファイルでは PBMAC1 アルゴリズムが使用されます。将来の JDK リリースでは、keystore.pkcs12.macAlgorithmセキュリティプロパティのデフォルト値が PBMAC1 アルゴリズムに変更される予定です。

JEP 524: PEM Encodings of Cryptographic Objects (Second Preview)

暗号オブジェクトをPEM形式に変換(エンコード)および復元(デコード)するためのSecound preview APIが提供され、JEP 524で定義されました。

JEP 524: PEM Encodings of Cryptographic Objects (Second Preview)
https://openjdk.org/jeps/524

PEMは、証明書、CRL、秘密鍵などのDERエンコードされた暗号データを転送および保存するために広く使用されている形式です。これは、数年前に実施されたJCE調査において最も要望の多かった機能の一つでした。JEPの「History」セクションには、first preview以降の変更点のリストが記載されています。主なAPIは2つあり、暗号オブジェクトをPEM形式にエンコードするためのPEMEncoderクラスと、PEMデータを暗号オブジェクトにデコードするためのPEMDecoderクラスです。また、DEREncodableというマーカーインターフェースも用意されており、X509CertificateX509CRLなどの既存クラスは、このインターフェースを実装するように改修されました。これにより、これらのオブジェクトをPEM形式でエンコード/デコードすることが容易になりました。

Class PEMEncoder
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/security/PEMEncoder.html
Class PEMDecoder
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/security/PEMDecoder.html
Interface DEREncodable
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/security/DEREncodable.html

PEMEncoderは暗号化用に設定することも可能で、これにより秘密鍵の暗号化とエンコードを1つのステップで行うことが容易になります。同様に、PEMDecoderも復号用に設定でき、これにより秘密鍵のデコードと復号を1つのステップで行うことが可能になります。より高度な用途向けに、既存のEncryptedPrivateKeyInfoクラスが拡張され、秘密鍵の暗号化と復号を容易にするいくつかの新しいメソッドが追加されました。

Class EncryptedPrivateKeyInfo
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/javax/crypto/EncryptedPrivateKeyInfo.html

以下は、KeyStoreから取得したX509CertificateをPEM形式にエンコードする例です。

    X509Certificate cert = (X509Certificate)keystore.getCertificate("mycert");
    PEMEncoder encoder = PEMEncoder.of();
    String pem = encoder.encodeToString(cert);

以下は、PEMをX509Certificateにデコードする例です。

    PEMDecoder decoder = PEMDecoder.of();
    X509Certificate cert = decoder.decode(pem, X509Certificate.class);

以下は、PrivateKeyをパスワードで暗号化し、PEM形式にエンコードする2つの例です。最初の例では、PEMEncoderを暗号化用に設定し、1つのメソッド呼び出しで秘密鍵の暗号化とエンコードを直接行います。

    PEMEncoder encoder = PEMEncoder.of();
    String pem = encoder.withEncryption(password).encodeToString(privateKey);

上記の例では、暗号化時にデフォルトパラメータを使用しています。2つ目の例では、EncryptedPrivateKeyInfoクラスを使用して、パスワードベースの暗号化アルゴリズムなどの追加パラメータで秘密鍵を暗号化し、その後PEM形式にエンコードしています。

    EncryptedPrivateKeyInfo epki =
        EncryptedPrivateKeyInfo.encrypt(privateKey, password,
            "PBEWithHmacSHA256AndAES_256", null, null);
    PEMEncoder encoder = PEMEncoder.of();
    String pem = encoder.encodeToString(epki);

New Security Property to Disable Algorithms at the JCE Layer [JDK-8244336]

jdk.crypto.disabledAlgorithms という新しいセキュリティプロパティが追加されました。これは、JCE/JCA API レベルで暗号アルゴリズムを無効化するために使用できます。このプロパティは、標準アルゴリズム名仕様で規定されたアルゴリズム名のリストを受け取ります。このセキュリティプロパティは、同名のシステムプロパティによって上書きされる可能性があります。

初期状態では、このプロパティは空であり、アルゴリズムは含まれていません。

これは、アプリケーション内のすべてのコードにわたって、包括的なレベルで暗号アルゴリズムの使用状況を検出できる非常に有用なプロパティです。

アルゴリズムの構文およびサポートされている JCE サービスの詳細については、java.security 設定ファイルの定義を参照してください。

Various Performance Improvements [JDK-8371820JDK-8371450JDK-8371259JDK-8365581]

AES、ML-DSA、および楕円曲線 (P256) アルゴリズムにおいて、多数のパフォーマンス改善が行われました。詳細については、リンクのIssueを参照してください。

Removed Obsolete Algorithms from Implementation Requirements [JDK-8361964]

DESede (3DES) アルゴリズムおよび PKCS1Padding を使用する Cipher アルゴリズムが、Java SE の実装要件から削除されました。これらのアルゴリズムはもはや推奨されておらず、要件として含めるべきではありません。削除された実装要件の完全なリストは以下の通りです。

カテゴリーアルゴリズム
AlgorithmParametersDESede
CipherDESede/CBC/NoPadding
DESede/CBC/PKCS5Padding
DESede/ECB/NoPadding
DESede/ECB/PKCS5Padding
RSA/ECB/PKCS1Padding
KeyGeneratorDESede
SecretKeyFactoryDESede

Added PBES2 Algorithms as New Implementation Requirements [JDK-8361964]

RFC 8018: PKCS #5: Password-Based Cryptography Specification Version 2.1 に記載されている以下の PBES2 アルゴリズムが、新しい要件として追加されました:

RFC 8018 PKCS #5: Password-Based Cryptography Specification Version 2.1
https://www.rfc-editor.org/rfc/rfc8018

カテゴリーアルゴリズム
AlgorithmParametersPBEWithHmacSHA256AndAES_128
PBEWithHmacSHA256AndAES_256
CipherPBEWithHmacSHA256AndAES_128
PBEWithHmacSHA256AndAES_256
MacPBEWithHmacSHA256
SecretKeyFactoryPBEWithHmacSHA256AndAES_128
PBEWithHmacSHA256AndAES_256
PBKDF2WithHmacSHA256

PKI

New Root CA Certificates [JDK-8359170]

cacertsキーストアにいくつかの新しいルートCA証明書が追加されました。これらのルート証明書は、Oracle JDK 25、24.0.2、21.0.8、17.0.16、11.0.27、および8u461のcacertsキーストアにも追加されています。

SectigoのルートCA証明書4個(TLS用2個、コード署名用2個)

Subject common name Distinguished name
Sectigo Public Server Authentication Root E46CN=Sectigo Public Server Authentication Root E46, O=Sectigo Limited, C=GB
Sectigo Public Server Authentication Root R46CN=Sectigo Public Server Authentication Root R46, O=Sectigo Limited, C=GB
Sectigo Public Code Signing Root E46CN=Sectigo Public Code Signing Root E46, O=Sectigo Limited, C=GB
Sectigo Public Code Signing Root R46CN=Sectigo Public Code Signing Root R46, O=Sectigo Limited, C=GB

Removed Root CA Certificates [JDK-8361212]

4つのAffirmTrustルート証明書がcacertsキーストアから削除されました。これらのルートCAは、所有者であるEntrustによって無効化され、今後サポートされなくなります。削除された4つのルートは以下の通りです。これらのルート証明書は、Oracle JDK 25.0.1、21.0.9、17.0.17、11.0.29、および 8u471 の cacerts キーストアからも削除済みです。

Subject common name Distinguished name
AffirmTrust CommercialCN=AffirmTrust Commercial, O=AffirmTrust, C=US
AffirmTrust NetworkingCN=AffirmTrust Networking, O=AffirmTrust, C=US
AffirmTrust PremiumCN=AffirmTrust Premium, O=AffirmTrust, C=US
AffirmTrust Premium ECCCN=AffirmTrust Premium ECC, O=AffirmTrust, C=US

TLS

Improved Checking in SunX509 KeyManagerFactory [JDK-8359956]

TLS接続用の証明書および鍵素材を提供するために使用されるデフォルトのSunX509 KeyManagerFactoryが改良され、選択された証明書が現在のアルゴリズム制約設定に準拠していることを確認するための追加チェックが実装されました。これにより、そのチェック処理はPKIX KeyManagerFactoryと一貫性を持つようになりました。

Class KeyManagerFactory
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/javax/net/ssl/KeyManagerFactory.html

具体的には、選択は以下のルールに基づいて行われます:

  1. ローカル証明書は、TLSのsignature_algorithms_cert拡張子で送信される、相手側がサポートする証明書署名アルゴリズムに対してチェックされます。
  2. ローカル証明書は、jdk.tls.disabledAlgorithmsおよびjdk.certpath.disabledAlgorithmsセキュリティプロパティで指定されたTLSアルゴリズム制約に対してチェックされます。
  3. ローカル証明書は、有効期間および証明書拡張子に基づいて優先順位が付けられます。

以前の動作は、システムプロパティ jdk.tls.SunX509KeyManager.certCheckingtrue に設定することで再有効化できます。

XML Signature

Disabled the XPath Filtering Transform [JDK-8314180]

XPath Filtering Transform (XPathフィルタリング変換) を使用するXML署名は、デフォルトで無効化されています。XPath変換は強力ですが、複雑さを招くリスクが高く、XML署名のベストプラクティス文書では推奨されていません。必要な場合、自己責任において、jdk.xml.dsig.secureValidationPolicyセキュリティプロパティからこの変換を削除することで、再度有効にすることができます。

あるいは、XPath Filtering Transformに関連する問題に対処するために設計されたXPath Filter 2 Transformへの置き換えを検討してください。

XPath Filtering Transform
https://www.w3.org/TR/xmldsig-core/#sec-XPath
XML Signature Best Practices
https://www.w3.org/TR/xmldsig-bestpractices/#prefer-xpath-filter2
XML-Signature XPath Filter 2.0
https://www.w3.org/TR/xmldsig-filter2/#sec-Intro

New Property to Specify SecureRandom [JDK-8359395]

jdk.xmldsig.SecureRandom という名前の新しい XML 署名プロパティが追加されました。これにより、JDK 実装が使用するデフォルトの SecureRandom の代わりに、特定の SecureRandom インスタンスを指定できるようになります。

これは、XML署名の生成に使用されるセキュア乱数をより細かく制御したい場合に役立ちます。

このプロパティを使用するには、XMLSignContextクラスのsetPropertyメソッドを呼び出し、プロパティ名と使用したいSecureRandomオブジェクトのインスタンスを指定します。

setProperty (Interface XMLCryptoContext)
https://docs.oracle.com/en/java/javase/25/docs/api/java.xml.crypto/javax/xml/crypto/XMLCryptoContext.html#setProperty(java.lang.String,java.lang.Object)
Class SecureRandom
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/security/SecureRandom.html

Tools

Signed JAR Support for ML-DSA [JDK-8349732]

JDK 21では、NISTがFIPS 204で規定し、Javaプラットフォーム向けにJEP 497で定義された量子耐性デジタル署名アルゴリズムであるML-DSAのサポートを追加しました。

FIPS 204, Module-Lattice-Based Digital Signature Standard | CSRC
https://csrc.nist.gov/pubs/fips/204/final
JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
https://openjdk.org/jeps/497

今回のリリースでは、そのサポートを拡張し、ML-DSAを使用したJARの署名機能を追加しました。これは、jarsignerユーティリティまたはJarSigner APIを使用して実行できます。

Class JarSigner
https://docs.oracle.com/en/java/javase/25/docs/api/jdk.jartool/jdk/security/jarsigner/JarSigner.html

以下は、jarsigner を使用して ML-DSA で JAR に署名する例です。

    $ jarsigner -keystore ks –sigalg ML-DSA-65 -signedjar signed.jar
      test.jar mldsa

java -XshowSettings:security:tls Now Shows TLS Named Groups and Signature Schemes [JDK-8351354JDK-8371074]

診断コマンド java -XshowSettings:security:tls は、有効なプロトコルや暗号スイートに加え、TLS ハンドシェイクで有効になっている TLS named group(または鍵交換アルゴリズム)および署名スキームを表示するようになりました。

以下は、新しい出力を示す実行例です。

    $ java -XshowSettings:security:tls
    Security TLS configuration (SunJSSE provider):
        Enabled Protocols:
            TLSv1.3
            TLSv1.2
   
        Enabled Cipher Suites:
            TLS_AES_256_GCM_SHA384
            TLS_AES_128_GCM_SHA256
            TLS_CHACHA20_POLY1305_SHA256
            TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
            TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
            TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
            TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
            TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
            TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
            TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
            TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
            TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
            TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
            TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
            TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
            TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
            TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
            TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
            TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
            TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
            TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
            TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
            TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
            TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
            TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
            TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
            TLS_DHE_RSA_WITH_AES_256_CBC_SHA
            TLS_DHE_DSS_WITH_AES_256_CBC_SHA
            TLS_DHE_RSA_WITH_AES_128_CBC_SHA
            TLS_DHE_DSS_WITH_AES_128_CBC_SHA
            TLS_EMPTY_RENEGOTIATION_INFO_SCSV

        Enabled Named Groups:
            X25519MLKEM768
            x25519
            secp256r1
            secp384r1
            secp521r1
            x448
            ffdhe2048
            ffdhe3072
            ffdhe4096
            ffdhe6144
            ffdhe8192

        Enabled Signature Schemes:
            ecdsa_secp256r1_sha256
            ecdsa_secp384r1_sha384
            ecdsa_secp521r1_sha512
            ed25519
            ed448
            rsa_pss_rsae_sha256
            rsa_pss_rsae_sha384
            rsa_pss_rsae_sha512
            rsa_pss_pss_sha256
            rsa_pss_pss_sha384
            rsa_pss_pss_sha512
            rsa_pkcs1_sha256
            rsa_pkcs1_sha384
            rsa_pkcs1_sha512
            dsa_sha256
            ecdsa_sha224
            rsa_sha224
            dsa_sha224
            ecdsa_sha1
            rsa_pkcs1_sha1
            dsa_sha1

Improved keytool Warning When Using JKS or JCEKS Keystores [JDK-8353749]

JKS または JCEKS キーストアが使用された際に keytool が表示する警告が改善され、これらのキーストアは将来的に削除される予定であること、およびキーストアを PKCS12 へ移行することを推奨するようになりました。JKS に対して表示される警告は、以下のようになっています。

"JKS uses outdated cryptographic algorithms and will be removed in a future release. Migrate to PKCS12 using:
keytool -importkeystore -srckeystore <filename> -destkeystore <filename> -deststoretype pkcs12" 

JCEKS に対する警告も同様です。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください