9 Java PKIプログラマーズ・ガイド

Java Certification Path APIは、証明書パス(証明書チェーンとも呼ばれる)を扱うためのクラスとインタフェースで構成されます。証明書パスは、特定の検証規則を満たす場合に、公開キーから主体へのマッピングを安全に確立するために使用されます。

PKIプログラマーズ・ガイドの概要

Java Certification Path APIは、証明書パスを作成、構築および検証するためのインタフェースと抽象クラスを定義します。 実装は、プロバイダ・ベースのインタフェースを使ってプラグインされます。

このAPIは、Java暗号化アーキテクチャ・リファレンス・ガイドで説明されている暗号化サービス・プロバイダ・アーキテクチャに基づいており、PKIX標準に従ってX.509証明書パスを構築および検証するためのアルゴリズム固有のクラスを含んでいます。PKIX標準は、IETF PKIXワーキング・グループによって開発されています。

このAPIは、最初はJava Community Processプログラムを使用して指定されました(Java Specification Request (JSR) 000055)。このAPIは、Java SE Development Kit (JDK) 1.4からJava SDKに含まれました。JSR 55: Certification Path APIを参照してください。

このドキュメントの対象読者

このドキュメントは、次の2つの条件のいずれかに該当する、経験ある開発者を対象にしています。

  1. 証明書パスを構築または検証する、セキュリティ保護されたアプリケーションを設計する人

  2. 証明書パスを構築または検証するためのサービス・プロバイダ実装を記述する人

このドキュメントは、暗号化サービス・プロバイダをすでに読んでいることが前提となっています。

公開キー証明書の概要

公開キー・アプリケーションおよびシステムのユーザーは、主体の公開キーが本物であること、つまり、関連する秘密キーが主体によって所有されていることを確信している必要があります。公開キー証明書は、この信頼を確立するのに使用されます。

公開キー(またはアイデンティティ)証明書は、アイデンティティへの公開キーのバインディングです。アイデンティティは、別のエンティティ(多くの場合、証明書発行局(CA)と呼ばれる)の秘密キーでデジタル署名されます。この項の残りの部分では、CAという用語は、証明書に署名するエンティティの意味で使用されます。

ユーザーは、主体の公開キー証明書に署名したCAの公開キーの信頼できるコピーを持っていない場合、署名しているCAを保証する別の公開キー証明書が必要です。この論理は、証明書の連鎖(または証明書パス)が信頼できるアンカーまたは最も信頼できるCAから検出されるまで、再帰的にターゲットの主体(一般にエンド・エンティティと呼ばれる)に適用されます。通常、もっとも信頼できるCAは、ユーザーが直接信頼するCAに宛てて発行した証明書によって指定されます。一般に証明書パスは順序付けされた証明書のリストで、通常の場合、エンド・エンティティの公開キー証明書と0個以上の付加的な証明書で構成されます。通常、証明書パスには1つ以上のエンコードがあります。これにより、証明書パスは、安全にネットワークを通じて伝送されたり、別のオペレーティング・システム・アーキテクチャへ送信されたりします。

次の図は、もっとも信頼できるCAの公開キー(CA 1)からターゲットの主体(Alice)への証明書パスを示しています。証明書パスは、CA2という名前の中間CAを介して、Aliceの公開キーとの信頼を確立します。

図9-1 CAの公開キー(CA 1)からターゲットの主体への証明書パス

図9-1の説明が続きます
「図9-1 CAの公開キー(CA 1)からターゲットの主体への証明書パス」の説明

証明書パスは、主体の公開キーの信頼を確立するため、信頼する前に検証する必要があります。検証では、署名を検証したり、各証明書が取り消されていないことをチェックしたりするなど、証明書パスに含まれている証明書に対するさまざまなチェックを行います。PKIX標準は、X.509証明書で構成される証明書パスの検証に関するアルゴリズムを定義します。

ユーザーは、もっとも信頼できるCAから主体への証明書パスを持っていないことがあります。証明書パスを構築または検出するサービスの提供は、公開キーに対応するシステムの重要な機能です。RFC 2587は、LDAP (Lightweight Directory Access Protocol)スキーマ定義を定義します。LDAPスキーマ定義により、LDAPディレクトリ・サービス・プロトコルを使用したX.509証明書パスの検出が容易になります。

証明書パスの構築および検証は、SSL/TLS/DTLS、S/MIME、IPsecなど、多くの標準セキュリティ・プロトコルの重要な一部です。Java Certification Path APIは、この機能をアプリケーションに統合する必要のある開発者に、クラスおよびインタフェースのセットを提供します。このAPIは、特定の証明書パスの構築、または検証アルゴリズム用にサービス・プロバイダ実装を記述する必要がある開発者、および実装に依存しない方式による証明書パスの作成、構築、検証のために標準アルゴリズムにアクセスする必要のある開発者にとって便利です。

X.509証明書と証明書失効リスト(CRL)

公開キー証明書とは、あるエンティティが発行したデジタル署名のある文書で、別のエンティティの公開キー(および他の情報)が特定の値であることを証明するものです。

次の表では、重要な用語をいくつか示します。

公開キー
公開鍵は、特定のエンティティに関連付けられた数です。公開鍵は、該当するエンティティとの間に信頼できる関係を持つ必要があるすべての人に対して公開することを意図したものです。公開キーは、署名を検証するのに使われます。
デジタル署名
データがデジタル署名されると、そのデータは、エンティティの「アイデンティティ」と、そのエンティティがデータの内容について知っていることを証明する署名とともに格納されます。エンティティの秘密キーを使って署名することで、データを偽造できなくなります。
アイデンティティ
エンティティを特定するための既知の方法です。システムによっては、公開キーをアイデンティティにするものがあります。公開キーの他にも、UNIX UIDや電子メール・アドレス、X.509識別名など、様々なものをアイデンティティとすることができます。
署名
署名は、エンティティ(署名者)の秘密キーを使い、あるデータに対して計算されるものです。
秘密キー
秘密キーとは、特定のエンティティのみが知っている数のことで、この数のことをそのエンティティの秘密キーと呼びます。秘密キーは、他に知られないように秘密にしておくことが前提になっています。非公開キーと公開キーは、すべての公開キー暗号化システムで対になって存在しています。DSAなどの典型的な公開キー暗号化システムの場合、1つの秘密キーは厳密に1つの公開キーに対応します。秘密キーは、署名を計算するのに使われます。
エンティティ
エンティティは、人、組織、プログラム、コンピュータ、企業、銀行など、一定の度合いで信頼の対象となるさまざまなものを指します。

公開キー暗号化では、その性質上、ユーザーの公開キーにアクセスする必要があります。大規模なネットワーク環境では、互いに通信しているエンティティ間で以前の関係が引き続き確立されていると仮定したり、使われているすべての公開キーを収めた信頼できるリポジトリが存在すると仮定したりすることは不可能です。このような公開キーの配布に関する問題を解決するために証明書が考案されました。現在では、証明書発行局(CA)が、信頼できる第三者として機能します。CAは、信頼されて、ほかのエンティティのために証明書に署名する(証明書を発行する)エンティティ(ビジネスなど)です。CAだけが、法的な契約による義務の下で、有効かつ信頼できる証明書を作成するものと見なされています。VeriSignThawteEntrustをはじめ、多くの公開CAが存在します。NetscapeやMicrosoftの認証サーバー、EntrustのCA製品などを所属組織内で利用すれば、独自の証明書発行局を運営することも可能です。

証明書を使うアプリケーション

現在、X.509証明書のアプリケーションでもっとも身近なものは、TLSプロトコルをサポートするWebブラウザ(Mozilla FirefoxやMicrosoft Internet Explorerなど)です。TLS (Transport Layer Security)は、ネットワーク・トラフィックにプライバシと認証機能を提供するセキュリティ・プロトコルです。TLSをサポートするブラウザは、TLSをサポートするWebサーバーとの間でだけ、このプロトコルを使うことができます。

X.509の証明書に依存する技術としては、ほかに次のものがあります。

  • 署名されたJava ARchiveやMicrosoft Authenticodeなど、さまざまなコード署名方式。
  • PEMやS/MIMEなど、機密保護された電子メールの各種標準。

証明書の取得方法

証明書を取得する基本的な方法としては、次の2つがあります。

  • 自分で作成する(keytoolなどの適切なツールを使用する)
  • 証明書発行局に証明書の発行を依頼する(直接要求する、またはkeytoolなどのツールを使用して要求を生成する)。

証明書の作成処理で必要になる主な入力には、次のものがあります。

  • 対になった公開キーと秘密キー。専用のツール(keytoolなど)やブラウザを使って生成されたものです。公開キーのみがだれに対しても提示されます。秘密キーは、データへの署名に使われます。他人に秘密キーを知られると、所有者になりすまされて、所有者に帰属する法的な文書を偽造されることにもなりかねません。
  • 認定されるエンティティ(自分など)についての情報を提供する必要があります。一般に、名前や勤務先住所などの情報が含まれます。CAに証明書の発行を依頼する場合、通常、情報が正しいことを証明するものを提示しなければなりません。

CAに証明書の発行を依頼する場合は、自分の非公開キーと自分についての情報を提出します。keytoolや、証明書署名要求の生成をサポートするブラウザなどのツールを使ってこの情報にデジタル署名し、CAに送ります。CAは証明書を生成して、送り返します。

自分で証明書を生成する場合は、同様の情報に加えて、さらに若干の情報(証明書の有効期間、シリアル番号など)を用意し、keytoolなどのツールを使って証明書を作成します。自己署名の証明書では受け入れられない場合があります。CAが提供する価値の1つは、中立で信頼できる紹介サービスを提供することであり、その一部は、認証サービス業務(CSP)の中で公開されている検証要件に基づいています。

X.509証明書の内容

X.509規格では、証明書に含める情報が定義されており、この情報を証明書に書き込む方法(データ形式)についても記述されています。すべてのX.509証明書は、署名のほかに次のデータを含んでいます。

バージョン
証明書に適用されるX.509規格のバージョンを特定します。証明書に指定できる情報は、バージョンによって異なります。これまでに、3つのバージョンが定義されています。
シリアル番号
証明書を作成したエンティティは、そのエンティティが発行する他の証明書と区別するために、証明書にシリアル番号を割り当てます。この情報は、様々な方法で使われます。たとえば、証明書が失効されると、シリアル番号が証明書失効リスト(CRL)に格納されます。
署名アルゴリズム識別子
証明書に署名を付けるときにCAが使ったアルゴリズムを特定します。
発行者名
証明書に署名したエンティティのX.500名です。エンティティは、通常はCAです。この証明書を使うことは、証明書に署名を付けたエンティティを信頼することを意味します。ルートまたはトップ・レベルのCAの証明書など、場合によっては発行者が自身の証明書に署名を付けることがある点に注意してください。
有効期間
各証明書は、かぎられた期間だけ有効になります。この期間は開始の日時と終了の日時によって指定され、数秒の短い期間から100年という長期にわたることもあります。選択される有効期間は、証明書への署名に使われる秘密キーの強度や証明書に支払う金額など、さまざまな要因で異なります。有効期間は、使用する秘密キーが損なわれない場合に、エンティティが公開キーを信頼できると期待される期間です。
サブジェクト名
証明書で公開キーが識別されているエンティティの名前です。この名前はX.500標準を使うので、インターネット全体で一意なものと想定されます。これはエンティティの識別名(DN)です。たとえば、

    CN=Java Duke, OU=Java Software Division, O=Sun Microsystems Inc, C=US
これらはそれぞれサブジェクトの通称、組織単位、組織、国を表します。
Subjectの公開キー情報
名前を付けられたエンティティの公開キーとアルゴリズム識別子です。アルゴリズム識別子では、公開キーに対して使われている公開キー暗号化システムおよび関連するキー・パラメータが指定されています。

X.509 Version 1は、1988年から利用されて広く普及しており、もっとも一般的です。

X.509 Version 2では、サブジェクトや発行者の名前をあとで再利用できるようにするために、サブジェクトと発行者の一意識別子の概念が導入されました。ほとんどの証明書プロファイル文書では、名前を再使用しないことと、証明書で一意な識別子を使わないことが、強く推奨されています。Version 2の証明書は、広くは使われていません。

X.509 Version 3はもっとも新しい(1996年)規格で、拡張機能の概念をサポートしています。これにより、だれでも拡張機能を定義でき、証明書に含めることができます。現在使われている一般的な拡張機能としては、KeyUsage (「署名専用」など、キーの使用を特定の目的に制限する)、AlternativeNames (DNS名、電子メール・アドレス、IPアドレスなど、他のアイデンティティを公開キーに関連付けることができる)などがあります。拡張機能には、criticalというマークを付けて、その拡張機能のチェックと使用を義務付けることができます。たとえば、criticalとマークされ、KeyCertSignが設定されたKeyUsageエクステンションが証明書に含まれている場合、この証明書をSSL通信中に提示すると、証明書が拒否されます。これは、証明書のエクステンションによって、関連する秘密キーが証明書の署名専用として指定されており、SSLでは使用できないためです。

証明書のすべてのデータは、ASN.1/DERと呼ばれる2つの関連規格を使ってエンコードされます。Abstract Syntax Notation 1はデータについて記述しています。Distinguished Encoding Rulesはデータの保存および転送の唯一の方法について記述しています。

証明書のアクセスと管理に使うJava API

java.security.certにあるCertificate APIには、次のクラスとインタフェースが含まれています。

  • CertificateFactoryクラスは、証明書ファクトリの機能を定義します。証明書ファクトリは、エンコーディングから証明書のオブジェクト、証明書失効リスト(CRL)のオブジェクト、および証明書パスのオブジェクトを生成するために使用されます。
  • Certificateクラスは、様々な証明書を管理するための抽象クラスです。形式は異なっていても重要な共通の使用方法を備えた、証明書のための抽象化です。たとえば、X.509とPGPなどは異なる種類の証明書ですが、一般的な証明書の機能(エンコードと検証など)と、公開キーなど一部の情報を共有しています。
  • CRLクラスは、様々な証明書失効リスト(CRL)を管理するための抽象クラスです。
  • X509Certificateクラスは、X.509証明書のための抽象クラスです。X.509証明書のすべての属性にアクセスするための標準的な手段を提供します。
  • X509Extensionインタフェースは、X.509拡張情報のためのインタフェースです。X.509 v3の証明書およびv2のCRLに定義されている拡張情報は、付加属性をユーザーや公開キーと関連付けるためのメカニズムを提供します。これは、証明書の階層やCRLの配布を管理するためのものです。
  • X509CRLクラスは、X.509証明書失効リスト(CRL)のための抽象クラスです。CRLは、タイムスタンプの付いたリストで、取り消された証明書を示しています。これは証明書発行局(CA)によって署名され、公開のリポジトリで自由に利用できるようになっています。
  • X509CRLEntryクラスは、CRLのエントリのための抽象クラスです。

X.509証明書の生成、表示、インポート、およびエクスポートのためのJavaツール

公開/秘密キー・ペアとX.509 v3証明書の作成、およびキーストアの管理に使用できる、keytoolというツールがあります。キーと証明書は、Javaアプリケーションおよびアプレットにデジタル署名を行うために使用されます(jarsignerを参照)。

キーストアとは、キーと証明書を保持する保護されたデータベースです。キーストアへのアクセスは、パスワードによって保護されます。キーストアのパスワードは、キーストアの作成時に作成者が定義し、変更できるのは、現在のパスワードを指定した場合のみです。また、キーストアに含まれる各秘密キーは、それぞれのパスワードによって保護できます。

keytoolを使用すると、ファイルとして保存されているX.509 v1、v2およびv3証明書の表示、インポートおよびエクスポートや、新しいv3証明書の生成ができます。例については、Java Platform, Standard Editionツール・リファレンスkeytoolの「例」の項を参照してください。

コア・クラスとインタフェース

Java Certification Path APIのコア・クラスは、アルゴリズムおよび実装に依存しない方式で証明書パスの機能をサポートするインタフェースおよびクラスで構成されています。

APIは、証明書を処理する既存のjava.security.certパッケージに構築され、その機能を拡張します。コア・クラスは、次のように基本、検証、構築およびストレージという4つのクラス・カテゴリに分けることができます。

Java Certification Path APIには、RFC 5280 (Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile)で定義されているPKIX証明書パス検証アルゴリズムで使用するためにモデル化された、アルゴリズム固有クラスのセットも含まれます。PKIXクラスを次に示します。

  • TrustAnchor

  • PKIXParameters

  • PKIXCertPathValidatorResult

  • PKIXBuilderParameters

  • PKIXCertPathBuilderResult

  • PKIXCertPathChecker

  • PKIXRevocationChecker

関連するCertification Path APIクラスをすべて説明するリファレンス・ドキュメントは、java.security.certにあります。

CertPath APIのクラスおよびインタフェースの大半は、スレッドセーフではありません。ただし、このガイドおよびAPI仕様で言及される例外もあります。スレッドに対して安全でない単一のオブジェクトに同時にアクセスする必要のある複数のスレッドは、互いに同期して必要なロックを行うものとします。複数のスレッドがそれぞれ個別のオブジェクトを処理する場合、それらのスレッドは同期する必要はありません。

基本のCertification Pathクラス

基本の証明書パス・クラスは、証明書パスをエンコードおよび表示する基本的な機能を提供します。Java Certification Path APIの主要な基本クラスはCertPathです。このクラスは、すべての型の証明書パスで共有される汎用的な部分をカプセル化します。アプリケーションは、CertificateFactoryクラスのインスタンスを使ってCertPathオブジェクトを生成します。

CertPathクラス

CertPathクラスは、証明書パスの抽象クラスです。すべての証明書パス・オブジェクトが共有する機能を定義します。様々な証明書パスの型は、それが異なる内容および順序付けスキームを持っていても、CertPathクラスをサブクラス化することによって実装できます。

すべてのCertPathオブジェクトは、直列化可能、不変、かつスレッドに対して安全です。さらに、次の特徴を備えています。

  • これは、証明書パスの証明書の型と対応しています。たとえば、X.509のようになります。CertPathの型は、次のメソッドを使って取得されます。

    
        public String getType()
    

    標準の証明書型については、CertificateFactoryの型を参照してください。

  • 証明書リスト

    getCertificatesメソッドは、証明書パスに含まれる証明書のリストを返します。

    
        public abstract List<? extends Certificate> getCertificates()
    
    このメソッドは、0個以上のjava.security.cert.CertificateオブジェクトのListを返します。返されるListおよびその中に含まれるCertificatesは、CertPathオブジェクトの内容を保護するため、変更できません。返される証明書の順序付けは、型に依存します。規則により、X.509型のCertPathオブジェクト内の証明書は、ターゲットとなる証明書から順に並べられ、信頼できるアンカーによって発行された証明書が最後に置かれます。つまり、証明書の発行者は、その次に続く証明書の主体になります。TrustAnchorを表す証明書を証明書パスに含めることはできません。ただし、検証されていないX.509のCertPathは、この規則に従っていないことがあります。PKIX CertPathValidatorは、この規則の違反を検出することにより、証明書パスが無効になりCertPathValidatorExceptionがスローされるのを防ぎます。
  • 1つ以上のエンコード

    CertPathオブジェクトは、1つ以上のエンコードをサポートします。これらは証明書パスの外部エンコード形式で、ネットワークを通じてパスを別の組織に転送する際に、パスの標準表示がJava仮想マシンの外部で必要なときに使用します。各パスはデフォルトの形式でエンコードされ、そのバイトは次のメソッドを使って返されます。

    
        public abstract byte[] getEncoded()
    
    一方、getEncoded(String)メソッドは、エンコード形式をString (例: PKCS7)として指定することにより、サポートされる特定のエンコードを返します。標準のエンコード形式については、CertPathのエンコードを参照してください。
    
        public abstract byte[] getEncoded(String encoding)
    
    また、getEncodingsメソッドは、サポートされるエンコード形式Stringでもイテレータを返します(デフォルトのエンコード形式が最初に返される)。
    
        public abstract Iterator<String> getEncodings()
    

すべてのCertPathオブジェクトはSerializableでもあります。直列化中にCertPathオブジェクトは代替CertPath.CertPathRepオブジェクトに解釈処理されます。これにより、基本的な実装にかかわらず、CertPathオブジェクトを同等の表現に直列化できます。

CertPathオブジェクトは、CertificateFactoryを使って、エンコードされたバイト配列またはCertificateのリストから生成されます。一方、CertPathBuilderは、もっとも信頼できるCAから特定の主体へのCertPathを探すために使用されます。CertPathオブジェクトが生成されると、それはCertPathValidatorvalidateメソッドに渡され、検証されます。これらの概念の詳細については、続くセクションで説明します。

CertificateFactoryクラス

CertificateFactoryクラスは、証明書ファクトリの機能を定義するエンジン・クラスです。CertificateCRLおよびCertPathオブジェクトを生成するために使用されます。

CertificateFactoryCertPathBuilderと混同しないでください。CertPathBuilder (後述)は、証明書パスが存在しないときに、証明書パスの検出または発見に使用されます。それに対してCertificateFactoryは、証明書パスがすでに検出されていて、エンコードされたバイト配列、またはCertificateの配列など、異なる形式で存在する内容から呼出し側がCertPathオブジェクトのインスタンスを生成する必要があるときに使用されます。

CertificateFactoryオブジェクトの作成

CertificateFactoryオブジェクトの作成の詳細は、Java暗号化アーキテクチャ・リファレンス・ガイドCertificateFactoryの項を参照してください。

CertPathオブジェクトの生成

CertificateFactoryのインスタンスは、CertificateオブジェクトのListから、またはCertPathのエンコードされた形式を含むInputStreamから、CertPathオブジェクトを生成します。CertPathと同様、それぞれのCertificateFactoryは、証明書パス(PKCS#7など)のデフォルトのエンコード形式をサポートします。CertPathオブジェクトを生成し、そのオブジェクトを入力ストリームから(デフォルトのエンコード形式で)読み込まれたデータを使って初期化するには、generateCertPathメソッドを使用します。

public final CertPath generateCertPath(InputStream inStream)

特定のエンコード形式から読み込まれたデータを使用する場合は次のようになります。

    public final CertPath generateCertPath(InputStream inStream, 
                                           String encoding)

サポートされているエンコード形式を調べるには、getCertPathEncodingsメソッドを使用します(デフォルトのエンコードが最初に返される)。

public final Iterator<String> getCertPathEncodings()

証明書パス・オブジェクトをCertificateオブジェクトのListから生成するには、次のメソッドを使用します。

public final CertPath generateCertPath(List<? extends Certificate> certificates)

CertificateFactoryは、ファクトリと同じ型のCertificatesで構成されたCertPathオブジェクトを常に返します。たとえば、X.509型のCertificateFactoryは、java.security.cert.X509Certificateのインスタンスである証明書で構成されたCertPathオブジェクトを返します。

次のコード例は、PKCS#7でエンコードされた、ファイルに格納されている証明書応答から証明書パスを生成する方法を示しています。

    // open an input stream to the file
    FileInputStream fis = new FileInputStream(filename);
    // instantiate a CertificateFactory for X.509
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // extract the certification path from
    // the PKCS7 SignedData structure
    CertPath cp = cf.generateCertPath(fis, "PKCS7");
    // print each certificate in the path
    List<Certificate> certs = cp.getCertificates();
    for (Certificate cert : certs) {
        System.out.println(cert);
    }

次に、KeyStoreから証明書チェーンをフェッチして、CertificateFactoryを使ってCertPathに変換する別のコード例を示します。

    // instantiate a KeyStore with type JKS
    KeyStore ks = KeyStore.getInstance("JKS");
    // load the contents of the KeyStore
    ks.load(new FileInputStream("./keystore"),
        "password".toCharArray());
    // fetch certificate chain stored with alias "sean"
    Certificate[] certArray = ks.getCertificateChain("sean");
    // convert chain to a List
    List certList = Arrays.asList(certArray);
    // instantiate a CertificateFactory for X.509
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // extract the certification path from
    // the List of Certificates
    CertPath cp = cf.generateCertPath(certList);

generateCertificatesという名前のCertificateFactoryに、Certificatesのシーケンスを構文解析する既存のメソッドがあることに注意してください。複数の証明書から成るエンコードでは、互いに関連性がないと思われる証明書のコレクションを解析する場合に、generateCertificatesを使用します。それ以外では、CertPathを生成し、CertPathValidator (後述)で検証する場合に、generateCertPathを使用します。

CertPathParametersインタフェース

CertPathParametersインタフェースは、特定の証明書パス・ビルダーまたは検証アルゴリズムで使用される一連のパラメータの透明な表現です。

このインタフェースの主な目的は、すべての証明書パスのパラメータの仕様をグループ化すること(およびそれらのパラメータに安全な型を提供すること)です。CertPathParametersインタフェースは、Cloneableインタフェースを拡張し、例外をスローしないclone()メソッドを定義します。このインタフェースのすべての固定実装は、必要に応じてObject.clone()メソッドを実装し、オーバーライドします。これにより、アプリケーションは、CertPathParametersオブジェクトを複製できます。

CertPathParametersインタフェースを実装しているオブジェクトは、CertPathValidatorおよびCertPathBuilderクラスのメソッドに引数として渡されます。一般に、CertPathParametersインタフェースの固定実装は、特定の証明書パスの構築または検証アルゴリズムに固有の入力パラメータのセットを保持します。たとえば、PKIXParametersクラスは、PKIX証明書パス検証アルゴリズムの入力パラメータのセットを保持するCertPathParametersインタフェースの実装です。このようなパラメータの1つに、呼出し側が検証処理のアンカーについて信頼する、もっとも信頼できるCAのセットがあります。このパラメータについては特に、PKIXParametersクラスを扱ったセクションで詳しく説明します。

Certification Path検証クラス

Java Certification Path APIには、証明書パスを検証するクラスおよびインタフェースが含まれています。アプリケーションは、CertPathValidatorクラスのインスタンスを使用してCertPathオブジェクトを検証します。成功すると、CertPathValidatorResultインタフェースを実装するオブジェクトに、検証アルゴリズムの結果が返されます。

CertPathValidatorクラス

CertPathValidatorクラスは、証明書パスの検証に使用されるエンジン・クラスです。

CertPathValidatorオブジェクトの生成

他のエンジン・クラスと同様に、特定の検証アルゴリズム用のCertPathValidatorオブジェクトを取得するには、CertPathValidatorクラスのgetInstance staticファクトリ・メソッドの1つを呼び出します。


        public static CertPathValidator getInstance(String algorithm)
        public static CertPathValidator getInstance(String algorithm, 
                                                    String provider)
        public static CertPathValidator getInstance(String algorithm, 
                                                    Provider provider)

algorithmパラメータは、証明書パス検証アルゴリズムの名前(「PKIX」など)です。標準のCertPathValidatorアルゴリズム名は、Javaセキュリティ標準アルゴリズム名にリストされています。

証明書パスの検証

CertPathValidatorオブジェクトが生成されると、validateメソッドを呼び出して、検証する証明書パスおよびアルゴリズム固有のパラメータ・セットを渡すことによって、パスを検証できます。


        public final CertPathValidatorResult 
                validate(CertPath certPath, CertPathParameters params)
                throws CertPathValidatorException, 
                       InvalidAlgorithmParameterException

検証アルゴリズムが成功すると、CertPathValidatorResultインタフェースを実装するオブジェクトに結果が返されます。そうでない場合は、CertPathValidatorExceptionがスローされます。CertPathValidatorExceptionには、CertPathを返すメソッドが含まれます。また、必要に応じて、アルゴリズムの失敗を引き起こした証明書のインデックスや、エラーの根本となる例外または原因を返すメソッドが含まれます。

validateメソッドに渡されるCertPathおよびCertPathParametersは、検証アルゴリズムによってサポートされた型である必要があります。それ以外の場合は、InvalidAlgorithmParameterExceptionがスローされます。たとえば、PKIXアルゴリズムを実装するCertPathValidatorインスタンスは、X.509型のCertPathオブジェクト、およびPKIXParametersのインスタンスであるCertPathParametersを検証します。

CertPathValidatorResultインタフェース

CertPathValidatorResultインタフェースは、証明書パス検証アルゴリズムの成功結果または出力の透明な表現です。

このインタフェースの主な目的は、すべての検証結果をグループ化し、型保証をすることです。CertPathParametersインタフェースと同様に、CertPathValidatorResultCloneableを拡張し、例外をスローしないclone()メソッドを定義します。これにより、アプリケーションは、CertPathValidatorResultオブジェクトを複製できます。

CertPathValidatorResultインタフェースを実装しているオブジェクトは、成功時にCertPathValidatorResultインタフェースのvalidateメソッドによって返されます。成功しなかった場合は、失敗の説明とともにCertPathValidatorExceptionがスローされます。一般に、CertPathValidatorResultインタフェースの固定実装は、特定の証明書パス検証アルゴリズムに固有の出力パラメータのセットを保持します。たとえば、PKIXCertPathValidatorResultクラスは、PKIX証明書パス検証アルゴリズムの出力パラメータを取得するメソッドを含むCertPathValidatorResultインタフェースの実装です。このようなパラメータの1つに、有効なポリシー・ツリーがあります。このパラメータについては特に、PKIXCertPathValidatorResultクラスを扱ったセクションで詳しく説明します。

次のコード例では、CertPathValidatorを作成し、それを使用して証明書パスを検証する方法を示します。この例は、validateメソッドに渡されるCertPathおよびCertPathParametersオブジェクトが事前に生成されていることを前提としています。より詳しい例は、PKIXクラスを説明したセクションにあります。


    // create CertPathValidator that implements the "PKIX" algorithm
    CertPathValidator cpv = null;
    try {
        cpv = CertPathValidator.getInstance("PKIX");
    } catch (NoSuchAlgorithmException nsae) {
        System.err.println(nsae);
        System.exit(1);
    }
    // validate certification path ("cp") with specified parameters ("params")
    try {
        CertPathValidatorResult cpvResult = cpv.validate(cp, params);
    } catch (InvalidAlgorithmParameterException iape) {
        System.err.println("validation failed: " + iape);
        System.exit(1);
    } catch (CertPathValidatorException cpve) {
        System.err.println("validation failed: " + cpve);
        System.err.println("index of certificate that caused exception: "
                + cpve.getIndex());
        System.exit(1);
    }

Certification Path構築クラス

Java Certification Path APIには、証明書パスを構築する(または検出する)ためのクラスが含まれています。アプリケーションは、CertPathBuilderクラスのインスタンスを使ってCertPathオブジェクトを構築します。成功すると、CertPathBuilderResultインタフェースを実装するオブジェクトに、構築の結果が返されます。

CertPathBuilderクラス

CertPathBuilderクラスは、証明書パスの構築に使用されるエンジン・クラスです。

CertPathBuilderオブジェクトの生成

他のエンジン・クラスと同様に、特定の構築アルゴリズム用のCertPathBuilderオブジェクトを取得するには、CertPathBuilderクラスのgetInstance staticファクトリ・メソッドの1つを呼び出します。


        public static CertPathBuilder getInstance(String algorithm)
        public static CertPathBuilder getInstance(String algorithm, 
                                                  String provider)
        public static CertPathBuilder getInstance(String algorithm, 
                                                  Provider provider)

algorithmパラメータは、証明書パス構築アルゴリズムの名前(「PKIX」など)です。標準のCertPathBuilderアルゴリズム名は、Javaセキュリティ標準アルゴリズム名にリストされています。

証明書パスの構築

CertPathBuilderオブジェクトが生成されると、buildメソッドを呼び出して、アルゴリズム固有のパラメータ仕様を渡すことによって、パスを構築できます。


        public final CertPathBuilderResult build(CertPathParameters params)
                throws CertPathBuilderException, 
                       InvalidAlgorithmParameterException

構築アルゴリズムが成功すると、CertPathBuilderResultインタフェースを実装するオブジェクトに結果が返されます。失敗した場合は、たとえば、基になる例外(存在する場合)とエラー・メッセージなど、エラーについての情報を含むCertPathBuilderExceptionがスローされます。

buildメソッドに渡されるCertPathParametersは、構築アルゴリズムによってサポートされた型である必要があります。それ以外の場合は、InvalidAlgorithmParameterExceptionがスローされます。

CertPathBuilderResultインタフェース

CertPathBuilderResultインタフェースは、証明書パス構築アルゴリズムの結果または出力の透明な表現です。

このインタフェースには、次に示すように、正常に構築された証明書パスを返すメソッドが含まれます。


        public CertPath getCertPath()

CertPathBuilderResultインタフェースの目的は、すべての構築結果をグループ化すること(およびそれらの構築結果に安全な型を提供すること)です。CertPathValidatorResultインタフェースと同様に、CertPathBuilderResultインタフェースは、Cloneableを拡張し、例外をスローしないclone()メソッドを定義します。これにより、アプリケーションは、CertPathBuilderResultオブジェクトを複製できます。

CertPathBuilderResultインタフェースを実装するオブジェクトは、CertPathBuilderbuildメソッドによって返されます。

次のコード例では、CertPathBuilderを作成し、それを使用して証明書パスを構築する方法を示します。この例は、buildメソッドに渡されるCertPathParametersオブジェクトが事前に生成されていることを前提としています。より詳しい例は、PKIXクラスを説明したセクションにあります。


    // create CertPathBuilder that implements the "PKIX" algorithm
    CertPathBuilder cpb = null;
    try {
        cpb = CertPathBuilder.getInstance("PKIX");
    } catch (NoSuchAlgorithmException nsae) {
        System.err.println(nsae);
        System.exit(1);
    }
    // build certification path using specified parameters ("params")
    try {
        CertPathBuilderResult cpbResult = cpb.build(params);
        CertPath cp = cpbResult.getCertPath();
        System.out.println("build passed, path contents: " + cp);
    } catch (InvalidAlgorithmParameterException iape) {
        System.err.println("build failed: " + iape);
        System.exit(1);
    } catch (CertPathBuilderException cpbe) {
        System.err.println("build failed: " + cpbe);
        System.exit(1);
    }

証明書/CRLストレージ・クラス

Java Certification Path APIには、リポジトリから証明書およびCRLを取得するCertStoreクラスが含まれています。

このクラスを使用すると、呼出し側は、CertPathValidatorまたはCertPathBuilderの実装が証明書およびCRLの検出に使用するリポジトリを指定できます。PKIXParametersクラスのaddCertStoresメソッドを参照してください。

CertPathValidator実装は、呼出し側がコールバック・メカニズムとして指定したCertStoreオブジェクトを使用してCRLをフェッチし、失効チェックを行います。同様に、CertPathBuilder実装は、CertStoreをコールバック・メカニズムとして使用して証明書をフェッチします。また、失効チェックを行っている場合はCRLをフェッチします。

CertStoreクラス

CertStoreクラスは、証明書および証明書失効リスト(CRL)のリポジトリとして機能するエンジン・クラスです。

このクラスは、CertPathBuilderおよびCertPathValidatorの実装によって、証明書およびCRLの検索のため、または汎用の証明書およびCRLの取得メカニズムとして使用されます。

CertStoreは、秘密キーおよび信頼できる証明書のキャッシュへのアクセスを提供するjava.security.KeyStoreクラスとは異なり、非常に大きくなる可能性がある、信頼されない証明書およびCRLのリポジトリへのアクセスを提供するように設計されています。たとえば、CertStoreのLDAP実装は、1つ以上のディレクトリに格納されている証明書およびCRLに対するアクセスを、LDAPプロトコルを使って提供します。

CertStoreオブジェクトのすべてのpublicメソッドは、スレッドセーフです。つまり、単一の(または複数の) CertStoreオブジェクト上で、複数のスレッドがこれらのメソッドを並行して呼び出しても、悪影響はありません。これにより、たとえばCertPathBuilderは、CRLを検索しながら同時にほかの証明書を検索できます。

CertStoreオブジェクトの生成

他のエンジン・クラスと同様に、特定のリポジトリ型用のCertStoreオブジェクトを取得するには、CertStoreクラスのgetInstance staticファクトリ・メソッドの1つを呼び出します。


        public static CertStore getInstance(String type, 
                CertStoreParameters params)
        public static CertStore getInstance(String type,
                CertStoreParameters params, String provider)
        public static CertStore getInstance(String type,
                CertStoreParameters params, Provider provider)

typeパラメータは、証明書リポジトリ型(「LDAP」など)の名前です。標準のCertStore型は、Javaセキュリティ標準アルゴリズム名にリストされています。

初期化パラメータ(params)は、リポジトリ型に固有のものです。たとえば、サーバー・ベースのリポジトリの初期化パラメータは、サーバーのホスト名およびポートを含みます。パラメータがこのCertStore型について無効な場合、InvalidAlgorithmParameterExceptionがスローされます。getCertStoreParametersメソッドは、CertStoreを初期化するために使用されたCertStoreParametersを返します。


        public final CertStoreParameters getCertStoreParameters()

証明書の取得

CertStoreオブジェクトを作成すると、getCertificatesメソッドを使用してリポジトリから証明書を取得できます。このメソッドは、CertSelectorオブジェクト(詳細は後述)を引数として取得します。この引数は、どの証明書が返されるかを決定する一連の選択条件を指定します。


        public final Collection<? extends Certificate> getCertificates(CertSelector selector) 
                throws CertStoreException

このメソッドは、選択条件を満たすjava.security.cert.CertificateオブジェクトのCollectionを返します。一致するものがない場合は、空のCollectionが返されます。リモート・リポジトリとの通信障害など、予期しないエラー状態が生じた場合は、通常、CertStoreExceptionがスローされます。

ある種のCertStore実装では、指定した選択条件に一致する証明書またはCRLをリポジトリ全体で検索できません。これらのインスタンスでは、CertStore実装は、証明書およびCRLを検索するセレクタで指定された情報を使用します。たとえば、LDAP CertStoreは、ディレクトリ内のすべてのエントリを検索しない場合があります。その代わりに、探している証明書を含んでいる可能性のあるエントリだけを検索します。提供されたCertSelectorが、LDAP CertStoreがどのエントリを検索する必要があるかを判断するための十分な情報を提供しない場合、LDAP CertStoreCertStoreExceptionをスローすることがあります。

CRLの取得

getCRLsメソッドを使ってリポジトリからCRLを取得することもできます。このメソッドは、CRLSelectorオブジェクト(詳細は後述)を引数として取得します。この引数は、どのCRLが返されるかを決定する一連の選択条件を指定します。


        public final Collection<? extends CRL> getCRLs(CRLSelector selector) 
                throws CertStoreException

このメソッドは、選択条件を満たすjava.security.cert.CRLオブジェクトのCollectionを返します。一致するものがない場合は、空のCollectionが返されます。

CertStoreParametersインタフェース

CertStoreParametersインタフェースは、特定のCertStoreで使用されるパラメータのセットの透明な表現です。

このインタフェースの主な目的は、すべての証明書ストレージ・パラメータ仕様をグループ化し、型保証をすることです。CertStoreParametersインタフェースは、Cloneableインタフェースを拡張し、例外をスローしないcloneメソッドを定義します。このインタフェースの実装は、必要に応じてObject.clone()メソッドを実装し、オーバーライドします。これにより、アプリケーションは、CertStoreParametersオブジェクトを複製できます。

CertStoreParametersインタフェースを実装しているオブジェクトは、CertStoreクラスのgetInstanceメソッドに引数として渡されます。CertStoreParametersインタフェースを実装している、LDAPCertStoreParametersCollectionCertStoreParametersという2つのクラスは、このAPIで定義されます。

LDAPCertStoreParametersクラス

LDAPCertStoreParametersクラスは、CertStoreParametersインタフェースの実装で、証明書およびCRLをLDAP型のCertStoreから取得するために最低限の初期化パラメータのセット(ディレクトリ・サーバーのホストおよびポート番号)を保持します。

LDAPCertStoreParametersを参照してください。

CollectionCertStoreParametersクラス

CollectionCertStoreParametersクラスは、CertStoreParametersインタフェースの実装で、証明書およびCRLをCollection型のCertStoreから取得するための初期化パラメータのセットを保持します。

CollectionCertStoreParametersを参照してください。

CertSelectorおよびCRLSelectorインタフェース

CertSelectorおよびCRLSelectorインタフェースは、証明書およびCRLのコレクションまたは大きなグループから、証明書およびCRLを選択するための一連の条件の仕様です。

インタフェースはグループ化され、すべてのセレクタの仕様に型の安全性を提供します。各セレクタ・インタフェースは、Cloneableを拡張し、例外をスローしないclone()メソッドを定義します。これにより、アプリケーションは、CertSelectorまたはCRLSelectorオブジェクトを複製できます。

CertSelectorおよびCRLSelectorインタフェースは、それぞれmatchという名前のメソッドを定義します。matchメソッドは、CertificateまたはCRLオブジェクトを引数として取得し、オブジェクトが選択条件を満たす場合、trueを返します。それ以外は、falseを返します。CertSelectorインタフェースのmatchメソッドは、次のようにして定義されます。


        public boolean match(Certificate cert)

CRLSelectorインタフェースについては、次のようにして定義されます。


        public boolean match(CRL crl)

一般に、これらのインタフェースを実装しているオブジェクトは、CertStoreクラスのgetCertificatesおよびgetCRLsメソッドにパラメータとして渡されます。これらのメソッドは、指定された選択条件に一致するCertStoreリポジトリから、CertificateまたはCRLCollectionを返します。また、CertSelectorは、証明書パスのターゲットまたはエンド・エンティティ証明書で、検証の制約を指定するためにも使用されます(例については、PKIXParameters.setTargetCertConstraintsメソッドを参照)。

X509CertSelectorクラス

X509CertSelectorクラスは、X.509証明書を選択するための一連の条件を定義するCertSelectorインタフェースの実装です。

X509Certificateオブジェクトは、matchメソッドによって選択されるには、指定された条件のすべてを満たす必要があります。この選択条件は、CertPathBuilder実装がX.509証明書パスを構築する際に、潜在的な証明書を検出するために使用するよう設計されています。

たとえば、X509CertSelectorsetSubjectメソッドを使用すると、PKIX CertPathBuilderは、部分的に完成された連鎖の中で、先行するX509Certificateの発行者名と一致しないX509Certificateをフィルタにかけることができます。X509CertSelectorオブジェクトで、この条件とともにその他の条件を設定することにより、CertPathBuilderは、無関係な証明書を破棄して、CertPathParametersオブジェクトで指定した要件を満たすX.509証明書パスをより簡単に探すことができます。

この項で説明したX.509証明書拡張機能の定義については、RFC 5280を参照してください。

X509CertSelectorオブジェクトの生成

X509CertSelectorオブジェクトは、次のようにしてデフォルトのコンストラクタを呼び出すことにより生成されます。


        public X509CertSelector()

最初は、条件は何も設定されていません(どのX509Certificateも一致)。

選択条件の設定

呼出し側は、選択条件を使用してX.509証明書の異なるコンポーネントを照合できます。ここでは、選択条件を設定するいくつかのメソッドについて説明します。X509CertSelectorを参照してください。

setIssuerメソッドは、発行者の条件を設定します。


        public void setIssuer(X500Principal issuer)
        public void setIssuer(String issuerDN)
        public void setIssuer(byte[] issuerDN)

指定された識別名(X500PrincipalRFC 2253 String、またはASN.1 DERエンコード形式)は、証明書にある発行者の識別名と一致する必要があります。nullの場合、発行者の識別名は問われません。識別名の表現には、型定義が適切で効率的なため、X500Principalを使用することをお勧めします。

同様に、setSubjectメソッドは主体の条件を設定します。


        public void setSubject(X500Principal subject)
        public void setSubject(String subjectDN)
        public void setSubject(byte[] subjectDN)

指定された識別名(X500Principal、RFC 2253 String、またはASN.1 DERエンコード形式)は、証明書にある主体の識別名と一致する必要があります。nullの場合、主体の識別名は問われません。

setSerialNumberメソッドは、serialNumberの条件を設定します。


        public void setSerialNumber(BigInteger serial)

指定されたシリアル番号は、証明書にある証明書シリアル番号と一致する必要があります。nullの場合、証明書シリアル番号は問われません。

setAuthorityKeyIdentifierメソッドは、authorityKeyIdentifierの条件を設定します。


        public void setAuthorityKeyIdentifier(byte[] authorityKeyID)

証明書には、指定された値と一致するAuthority Key Identifier拡張機能が含まれている必要があります。nullの場合、authorityKeyIdentifier条件に関するチェックは行われません。

setCertificateValidメソッドは、certificateValidの条件を設定します。


        public void setCertificateValid(Date certValid)

指定された日付は、証明書の証明書有効期間内に収まる必要があります。nullの場合、どの日付も有効です。

setKeyUsageメソッドは、keyUsageの条件を設定します。


        public void setKeyUsage(boolean[] keyUsage)

証明書のKey Usage Extensionは、指定されたキー使用法の値(trueに設定されている値)を許可する必要があります。nullの場合、keyUsageの確認は行われません。

選択条件の取得

各選択条件の現在の値は、該当するgetメソッドを使って取得できます。X509CertSelectorを参照してください。

ここでは、X509CertSelectorクラスを使ってLDAP CertStoreからX.509証明書を取得する例を取り上げます。

はじめに、LDAPサーバーのホスト名およびポートを含むCertStoreオブジェクトの初期化に使用するLDAPCertStoreParametersオブジェクトを生成します。


        LDAPCertStoreParameters lcsp = new 
                LDAPCertStoreParameters("ldap.sun.com", 389);

次に、CertStoreオブジェクトを生成し、次の文のようにして、LDAPCertStoreParametersオブジェクトを渡します。


        CertStore cs = CertStore.getInstance("LDAP", lcsp);

この呼出しは、RFC 2587で定義されたスキーマを使って、証明書およびCRLをLDAPリポジトリから取得するCertStoreオブジェクトを生成します。

次のコードのブロックは、有効期限内のエンド・エンティティの証明書をすべて取得するX509CertSelectorを確立します。この証明書は、1)デジタル署名を許可するキーの利用法、および2)特定の電子メール・アドレスとともに主体の代替名を持つ特定の主体に発行されます。


        X509CertSelector xcs = new X509CertSelector();

        // select only unexpired certificates
        xcs.setCertificateValid(new Date());

        // select only certificates issued to
        // 'CN=alice, O=xyz, C=us'
        xcs.setSubject(new X500Principal("CN=alice, O=xyz, C=us"));

        // select only end-entity certificates
        xcs.setBasicConstraints(-2);

        // select only certificates with a digitalSignature
        // keyUsage bit set (set the first entry in the
        // boolean array to true)
        boolean[] keyUsage = {true};
        xcs.setKeyUsage(keyUsage);

        // select only certificates with a subjectAltName of
        // 'alice@xyz.example.com' (1 is the integer value of 
        // an RFC822Name)
        xcs.addSubjectAlternativeName(1, "alice@xyz.example.com");

次に、以前に生成したCertStoreオブジェクトのgetCertificatesメソッドにセレクタを渡します。


        Collection<Certificate> certs = cs.getCertificates(xcs);

PKIX CertPathBuilderは、潜在的な証明書の検出およびソートを容易にするため、同様のコードを使用して、検証制約またはその他の条件を満たさない潜在的な証明書を破棄することがあります。

X509CRLSelectorクラス

X509CRLSelectorクラスは、X.509 CRLを選択する一連の条件を定義するCRLSelectorインタフェースの実装です。

X509CRLオブジェクトは、matchメソッドによって選択されるには、指定された条件のすべてを満たす必要があります。選択条件は、リポジトリからCRLを取得する必要のあるCertPathValidatorまたはCertPathBuilder実装が、X.509証明書パスにある証明書の失効ステータスをチェックするのに役立つよう設計されています。

たとえば、X509CRLSelectorsetDateAndTimeメソッドを使用すると、PKIX CertPathValidatorは、指示された時間のあとに発行された、または指示された時間の前に期限が切れるX509CRLをフィルタにかけることができます。X509CRLSelectorオブジェクトで、この条件とともにその他の条件を設定することにより、CertPathValidatorは、無関係なCRLを破棄して、証明書が取り消されているかどうかをより簡単にチェックできます。

この項で説明したX.509 CRLフィールドおよび拡張機能の定義については、RFC 5280を参照してください。

X509CRLSelectorオブジェクトの生成

X509CRLSelectorオブジェクトは、次のようにしてデフォルトのコンストラクタを呼び出すことにより生成されます。


        public X509CRLSelector()

最初は、条件は何も設定されていません(どのX509CRLも一致)。

選択条件の設定

呼出し側は、選択条件を使用してX.509 CRLの異なるコンポーネントを照合できます。ここでは、選択条件を設定するほとんどのメソッドについて説明します。残りのメソッドの詳細は、X509CRLSelectorクラスのAPIドキュメントを参照してください。

setIssuersおよびsetIssuerNamesメソッドは、issuerNamesの条件を設定します。


        public void setIssuers(Collection<X500Principal> issuers)
        public void setIssuerNames(Collection<?> names)

CRLにある発行者の識別名は、指定された識別名の少なくとも1つと一致する必要があります。X500Principalを使用する識別名の表現は型定義が適切で効率的なため、setIssuersメソッドをお勧めします。setIssuerNamesメソッドの場合、names引数の各エントリは、Stringまたはバイト配列(それぞれ、RFC 2253またはASN.1 DERエンコード形式の名前を表す)のどちらかです。nullの場合、発行者の識別名は問われません。

setMinCRLNumberおよびsetMaxCRLNumberメソッドは、minCRLNumberおよびmaxCRLNumberの条件を設定します。


        public void setMinCRLNumber(BigInteger minCRL)
        public void setMaxCRLNumber(BigInteger maxCRL)

CRLには、CRL Number拡張機能が必要です。この拡張機能は、setMinCRLNumberメソッドが呼び出された場合に指定された値以上になり、setMaxCRLNumberメソッドが呼び出された場合に指定された値以下になる値を持ちます。これらのメソッドの1つに渡された値がnullの場合、対応するチェックは行われません。

setDateAndTimeメソッドは、dateAndTimeの条件を設定します。


        public void setDateAndTime(Date dateAndTime)

指定された日付は、CRLのthisUpdateコンポーネントの値と同じかまたはそれよりあとで、さらにnextUpdateコンポーネントの値より前である必要があります。nullの場合、dateAndTimeのチェックは行われません。

setCertificateCheckingメソッドは、失効ステータスがチェックされている証明書を設定します。


        public void setCertificateChecking(X509Certificate cert)

これは、条件ではありません。特定の証明書の失効をチェックする際に、CertStoreが関連するCRLを検索するのに役立つオプション情報です。nullが指定された場合、このようなオプション情報は提供されません。アプリケーションは、特定の証明書の失効をチェックする際、常にこのメソッドを呼び出し、CertStoreが正しいCRLを検索して無関係なCRLをフィルタすることができるよう、より多くの情報を提供する必要があります。

選択条件の取得

各選択条件の現在の値は、該当するgetメソッドを使って取得できます。これらのメソッドの詳細は、X509CRLSelectorクラスのAPIドキュメントを参照してください。

CRLをLDAPリポジトリから取得するX509CRLSelectorの生成方法は、X509CertSelectorの例と同様です。特定のCAによって発行され、最小のCRL番号を持つ、現在(現在の日付および時間)のCRLすべてを取得すると仮定します。まず、X509CRLSelectorオブジェクトを生成し、適当なメソッドを呼び出して選択条件を設定します。


        X509CRLSelector xcrls = new X509CRLSelector();
        // select CRLs satisfying current date and time
        xcrls.setDateAndTime(new Date());
        // select CRLs issued by 'O=xyz, C=us'
        xcrls.addIssuerName("O=xyz, C=us");
        // select only CRLs with a CRL number at least '2'
        xcrls.setMinCRLNumber(new BigInteger("2"));

次に、X509CertSelectorの例で生成されたCertStoreオブジェクトのgetCRLsメソッドにセレクタを渡します。


        Collection<CRL> crls = cs.getCRLs(xcrls);

PKIXクラス

Java Certification Path APIには、PKIX証明書パス検証アルゴリズムで使用するためにモデル化されている、アルゴリズム固有の一連のクラスが含まれています。

PKIX証明書パス検証アルゴリズムは、RFC 5280: インターネットX.509公開キー・インフラストラクチャの証明書および証明書失効リスト(CRL)のプロファイルで定義されています。

TrustAnchorクラス

TrustAnchorクラスは、X.509証明書パスの検証のための信頼できるアンカーとして使用される、最も信頼できるCAを表します。

TrustAnchorには、CAの公開キー、CAの名前、およびこのキーを使用して検証できるパスのセットに対する制約が含まれます。これらのパラメータは、信頼できるX509Certificateの形式で、または個別のパラメータとして指定できます。

すべてのTrustAnchorオブジェクトは、不変で、スレッドに対して安全です。つまり、単一の(または複数の) TrustAnchorオブジェクト上で、このクラスに定義されたメソッドを複数のスレッドが同時に呼び出しても、悪影響はありません。TrustAnchorオブジェクトは、不変かつスレッドに対して安全でなければならないので、アクセスの調整を心配することなく、オブジェクトをさまざまなコードに渡すことができます。

ノート:

このクラスはPKIXクラスとして説明されていますが、その他のX.509証明書パス検証アルゴリズムで使用されることもあります。

TrustAnchorオブジェクトの生成

TrustAnchorオブジェクトのインスタンスを生成するには、呼出し側は、信頼できるX509Certificateまたは公開キーと識別名のペアとして、「もっとも信頼できるCA」を指定する必要があります。また、呼出し側はオプションで、初期化の際に検証アルゴリズムが信頼できるアンカーに適用する名前の制約を指定することもできます。PKIXアルゴリズムでは、信頼できるアンカーに適用する名前の制約をサポートする必要がないため、PKIX CertPathValidatorまたはCertPathBuilderは、このパラメータをサポートすることなく例外をスローすることもできます。次のコンストラクタのうちの1つを使って、TrustAnchorオブジェクトを生成します。


        public TrustAnchor(X509Certificate trustedCert, 
                byte[] nameConstraints)
        public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey, 
                byte[] nameConstraints)
        public TrustAnchor(String caName, PublicKey pubKey, 
                byte[] nameConstraints)

nameConstraintsパラメータは、NameConstraints拡張機能のASN.1 DERエンコードを含むバイト配列として指定されます。名前の制約がデコードできない(正しく書式設定されない)場合、IllegalArgumentExceptionがスローされます。

パラメータ値の取得

次のように、対応するgetメソッドを使って、各パラメータを取得できます。


        public final X509Certificate getTrustedCert()
        public final X500Principal getCA()
        public final String getCAName()
        public final PublicKey getCAPublicKey()
        public final byte[] getNameConstraints()

ノート:

信頼できるアンカーが公開キーと名前のペアとして指定されている場合、getTrustedCertメソッドはnullを返します。同様に、信頼できるアンカーがX509Certificateとして指定されている場合、getCAgetCAName、およびgetCAPublicKeyメソッドはnullを返します。
PKIXParametersクラス

PKIXParametersClassクラスは、PKIX証明書パス検証アルゴリズムにより定義された入力パラメータのセットを指定します。また、いくつかの有用な追加パラメータも含んでいます。

このクラスは、CertPathParametersインタフェースを実装します。

X.509 CertPathオブジェクトおよびPKIXParametersオブジェクトは、PKIXアルゴリズムを実装しているCertPathValidatorインスタンスのvalidateメソッドに引数として渡されます。CertPathValidatorは、パラメータを使って、PKIX証明書パスの検証アルゴリズムを初期化します。

PKIXParametersオブジェクトの生成

PKIXParametersオブジェクトのインスタンスを生成するには、呼出し側は、PKIX検証アルゴリズムによる定義に従って「もっとも信頼できるCA」を指定する必要があります。もっとも信頼できるCAは、次のように、2つのコンストラクタのうちの1つを使って指定できます。


        public PKIXParameters(Set<TrustAnchor> trustAnchors) 
            throws InvalidAlgorithmParameterException
        public PKIXParameters(KeyStore keystore)
            throws KeyStoreException, InvalidAlgorithmParameterException

最初のコンストラクタを使用すると、呼出し側は、もっとも信頼できるCAをTrustAnchorオブジェクトのSetとして指定できます。かわりに、呼出し側は2番目のコンストラクタを使って、信頼できる証明書のエントリを含むKeyStoreインスタンスを指定できます。その各エントリは、もっとも信頼できるCAとみなされます。

パラメータ値の設定

PKIXParametersオブジェクトを作成すると、呼出し側は、様々なパラメータを設定(またはその現在の値を置換)できます。ここでは、パラメータを設定するためのいくつかのメソッドについて説明します。その他のメソッドの詳細は、PKIXParametersのAPIドキュメントを参照してください。

setInitialPoliciesメソッドは、PKIX検証アルゴリズムによって指定されたとおりに、初期ポリシー識別子を設定します。Setの要素は、Stringとして表現されたオブジェクト識別子(OID)です。initialPoliciesパラメータがnullであるか、または設定されていない場合、どのポリシーも受入れ可能です。


        public void setInitialPolicies(Set<String> initialPolicies)

setDateメソッドは、パスの妥当性を判定するための時間を設定します。dateパラメータが設定されていないか、またはnullである場合、現在の日付が使用されます。


        public void setDate(Date date)

setPolicyMappingInhibitedメソッドは、ポリシー・マッピング禁止フラグの値を設定します。指定されていない場合、フラグのデフォルト値はfalseです。


        public void setPolicyMappingInhibited(boolean val)

setExplicitPolicyRequiredメソッドは、明示的なポリシー要求フラグの値を設定します。指定されていない場合、フラグのデフォルト値はfalseです。


        public void setExplicitPolicyRequired(boolean val)

setAnyPolicyInhibitedメソッドは、ポリシー禁止フラグの値を設定します。指定されていない場合、フラグのデフォルト値はfalseです。


        public void setAnyPolicyInhibited(boolean val)

setTargetCertConstraintsメソッドを使用すると、呼出し側は、ターゲットまたはエンド・エンティティの証明書に制約を設定できます。たとえば、呼出し側は、ターゲットの証明書に特定の主体名を含むよう指定できます。制約は、CertSelectorオブジェクトとして指定されます。selectorパラメータがnullであるか、または設定されていない場合、ターゲットの証明書に制約は定義されません。


        public void setTargetCertConstraints(CertSelector selector)

setCertStoresメソッドを使用すると、呼出し側は、CertPathValidatorのPKIX実装がパス検証用CRLを検索するために使用するCertStoreオブジェクトのListを指定できます。これにより、CRLの位置を指定する拡張可能なメカニズムが提供されます。setCertStoresメソッドは、CertStoreオブジェクトのListをパラメータとして取得します。リスト中の最初のCertStoreは、後のエントリに優先します。


        public void setCertStores(List<CertStore> stores)

setCertPathCheckersメソッドを使用すると、呼出し側は、実装に固有の証明書パスのチェッカを生成することによってPKIX検証アルゴリズムを拡張できます。たとえば、このメカニズムは、非公開証明書の拡張情報を処理するために使用されます。setCertPathCheckersメソッドは、PKIXCertPathCheckerオブジェクト(後述)のリストをパラメータとして取得します。


        public void setCertPathCheckers(List<PKIXCertPathChecker> checkers)

setRevocationEnabledメソッドを使用すると、呼出し側は失効チェックを無効にできます。失効チェックは、PKIX検証アルゴリズムに必要なチェックなので、デフォルトでは有効になっています。ただし、PKIXでは、失効のチェック方法は定義しません。たとえば、実装はCRLまたはOCSPを使用することがあります。このメソッドを使用すると、呼出し側は、実装でデフォルトに設定された失効チェック・メカニズムが適当でない場合に、それを無効にできます。そのあとで、setCertPathCheckersメソッドを呼び出し、代わりとなるメカニズムを実装するPKIXCertPathCheckerに渡すことにより、別の失効チェック・メカニズムを指定できます。


        public void setRevocationEnabled(boolean val)

setPolicyQualifiersRejectedメソッドを使用すると、呼出し側は、ポリシー修飾子の処理を有効または無効に設定できます。PKIXParametersオブジェクトが生成されると、このフラグはtrueに設定されます。この設定は、ポリシー修飾子を処理するためのもっとも一般的な(かつ簡単な)方法を反映します。より複雑なポリシーを使用するアプリケーションでは、このフラグをfalseに設定する必要があります。


        public void setPolicyQualifiersRejected(boolean qualifiersRejected)

パラメータ値の取得

各パラメータの現在の値は、該当するgetメソッドを使って取得できます。これらのメソッドの詳細は、Class PKIXParametersのAPIドキュメントを参照してください。

PKIXCertPathValidatorResultクラス

PKIXCertPathValidatorResultクラスは、PKIX証明書パス検証アルゴリズムの結果を表します。

このクラスは、CertPathValidatorResultインタフェースを実装します。 検証アルゴリズムの実行結果である有効なポリシー・ツリーおよび主体の公開キーが保持され、それらを返すためのメソッド(getPolicyTree()およびgetPublicKey())が含まれます。PKIXCertPathValidatorResultのインスタンスは、PKIXアルゴリズムを実装するCertPathValidatorオブジェクトのvalidateメソッドによって返されます。

このクラスの詳細は、PKIXCertPathValidatorResultのAPIドキュメントを参照してください。

PolicyNodeインタフェースおよびPolicyQualifierInfoクラス

PKIX検証アルゴリズムは、証明書ポリシー処理に関連のあるいくつかの出力を定義します。ほとんどのアプリケーションは、これらの出力を使用する必要はありませんが、PKIX検証を実装しているかまたはアルゴリズムを構築しているプロバイダはすべて、それらの出力をサポートする必要があります。

PolicyNodeインタフェースは、PKIX証明書パス検証が正常に実行されると作成される有効なポリシー・ツリーのノードを表します。アプリケーションは、PKIXCertPathValidatorResultgetPolicyTreeメソッドを使って、有効なポリシー・ツリーのルートを取得できます。ポリシー・ツリーの詳細は、RFC 5280を参照してください。

PolicyNodegetPolicyQualifiersメソッドは、PolicyQualifierInfoオブジェクトのSetを返します。その各オブジェクトは、このポリシーが適用される適切な証明書のCertificate Policies拡張情報に含まれるポリシー修飾子を表します。

ほとんどのアプリケーションでは、有効なポリシー・ツリーおよびポリシー修飾子を調べる必要はありません。PKIXParametersでポリシー関連のパラメータを設定することにより、アプリケーションのポリシー処理目標を実現できます。ただし、有効なポリシー・ツリーは、より複雑なアプリケーション、特にポリシー修飾子を処理するアプリケーションに利用できます。

これらのクラスの詳細は、Interface PolicyNodeおよびPolicyQualifierInfoのAPIドキュメントを参照してください。

例9-1 PKIXアルゴリズムを使った証明書パスの検証例

ここでは、PKIX検証アルゴリズムを使った証明書パスの検証の例を取り上げます。例では、ほとんどの例外処理を無視し、信頼できるアンカーの証明書パスおよび公開キーがすでに生成されているものと仮定します。

まず、次の行のようにして、CertPathValidatorを生成します。


    CertPathValidator cpv = CertPathValidator.getInstance("PKIX");

次のステップで、TrustAnchorオブジェクトを生成します。このオブジェクトは、証明書パスの検証にアンカーとして使用されます。この例では、もっとも信頼できるCAは公開キーおよび名前(名前制約は適用されず、nullとして指定される)として指定されます。


    TrustAnchor anchor = new TrustAnchor("O=xyz,C=us", pubkey, null);

次のステップで、PKIXParametersオブジェクトを生成します。これを使用して、PKIXアルゴリズムで使用されるパラメータを移入します。この例では、コンストラクタに、前のステップで生成した要素TrustAnchorを1つだけ含むSetを渡します。


    PKIXParameters params = new PKIXParameters(Collections.singleton(anchor));

次に、検証アルゴリズムにより使用される制約またはその他のパラメータを持つ、パラメータ・オブジェクトを移入します。この例では、explicitPolicyRequiredフラグを有効にし、初期ポリシーOIDのセット(セットの内容は示されない)を指定します。


    // set other PKIX parameters here
    params.setExplicitPolicyRequired(true);
    params.setInitialPolicies(policyIds);

最後のステップは、生成済みの入力パラメータ・セットを使った証明書パスの検証です。


    try {
        PKIXCertPathValidatorResult result =
            (PKIXCertPathValidatorResult) cpv.validate(certPath, params);
        PolicyNode policyTree = result.getPolicyTree();
        PublicKey subjectPublicKey = result.getPublicKey();
    } catch (CertPathValidatorException cpve) {
        System.out.println("Validation failure, cert[" 
            + cpve.getIndex() + "] :" + cpve.getMessage());
    }

検証アルゴリズムが成功したら、その検証アルゴリズムで生成されたポリシー・ツリーおよび主体の公開キーを、PKIXCertPathValidatorResultgetPolicyTreeおよびgetPublicKeyメソッドを使って取得します。

そうでない場合は、CertPathValidatorExceptionがスローされるため、呼出し側は例外をキャッチして、エラー・メッセージや障害を引き起こした証明書のインデックスなど、障害のいくつかの詳細について出力できます。

PKIXBuilderParametersクラス

PKIXBuilderParametersクラスは、 CertPathBuilderクラスで使用するパラメータのセットを指定します。

PKIXParametersクラスを拡張するこのクラスは、PKIX証明書パス検証アルゴリズムに従って検証される証明書パスを構築するCertPathBuilderで使用されるパラメータのセットを指定します。

PKIXBuilderParametersオブジェクトは、PKIXアルゴリズムを実装したCertPathBuilderインスタンスのbuildメソッドに引数として渡されます。すべてのPKIX CertPathBuilderは、PKIX証明書パスの検証アルゴリズムに従って検証されている証明書パスを返す必要があります

PKIX CertPathBuilderが構築されたパスの検証に使用するメカニズムが、実装の詳細であることに注目してください。たとえば、実装はまず、最低限の検証を行ったパスを構築し、次にPKIXCertPathValidatorのインスタンスを使ってパスを完全に検証します。より効率的な実装は、パスの構築中に多くのパスを検証し、検証の障害または行き詰まりが発生した場合には、前の段階に戻ります。

PKIXBuilderParametersオブジェクトの生成

PKIXBuilderParametersオブジェクトの生成は、PKIXParametersオブジェクトの生成と同様です。ただし、PKIXBuilderParametersオブジェクトを生成するときに、呼出し側は、ターゲットまたはエンド・エンティティの証明書に制約を指定する必要があります。これらの制約は、ターゲットの証明書を探すのに十分な情報をCertPathBuilderに提供する必要があります。制約は、CertSelectorオブジェクトとして指定されます。次のコンストラクタのうちの1つを使って、PKIXBuilderParametersオブジェクトを生成します。


        public PKIXBuilderParameters(Set<TrustAnchor> trustAnchors, 
                CertSelector targetConstraints)
                throws InvalidAlgorithmParameterException
        public PKIXBuilderParameters(KeyStore keystore, 
                CertSelector targetConstraints) 
                throws KeyStoreException, InvalidAlgorithmParameterException
                                                

パラメータ値の取得/設定

PKIXBuilderParametersクラスは、PKIXParametersクラスで設定できるすべてのパラメータを継承します。さらに、setMaxPathLengthメソッドを呼び出して、証明書パス内の最大数の証明書に制限を設定することもできます。


        public void setMaxPathLength(int maxPathLength)

maxPathLengthパラメータは、証明書パスに存在できる非自動発行の中間証明書の最大数を指定します。PKIXアルゴリズムを実装しているCertPathBuilderインスタンスでは、指定された長さよりも長いパスを構築することはできません。値が0の場合、パスは単一の証明書だけを含むことができます。値が -1の場合、パスの長さは制約を受けません(つまり上限はない)。最大パス長を指定しなかった場合、デフォルトの5になります。このメソッドは、呼出し側の要求を満たすかどうかにかかわりなく、CertPathBuilderが長いパスを構築するのにリソースおよび時間を費やさないようにするために便利です。

パス内のCA証明書にBasic Constraints拡張機能が含まれている場合、結果がより短い証明書パスのときは常に、拡張機能のpathLenConstraintコンポーネントの値で maxPathLengthパラメータの値をオーバーライドします。また、対応するgetMaxPathLengthメソッドにより、このパラメータを取得することもできます。


        public int getMaxPathLength()

また、PKIXParametersクラスから継承されたsetCertStoresメソッドは、通常、CertPathBuilderのPKIX実装によって、パスを検証するためのCRLの検索だけでなく、パスを構築するための証明書の検索にも使用されます。これにより、証明書およびCRLの位置を指定する拡張可能なメカニズムが提供されます。

PKIXCertPathBuilderResultクラス

PKIXCertPathBuilderResultクラスは、PKIX証明書パス構築アルゴリズムの成功結果を表します。

このクラスは、PKIXCertPathValidatorResultクラスを拡張し、CertPathBuilderインタフェースを実装します。 PKIXCertPathBuilderResultのインスタンスは、PKIXアルゴリズムを実装するCertPathBuilderオブジェクトのbuildメソッドによって返されます。

PKIXCertPathBuilderResultインスタンスのgetCertPathメソッドは、常にPKIX証明書パスの検証アルゴリズムを使って検証されたCertPathオブジェクトを返します。返されたCertPathオブジェクトには、パスの固定に使用されていたもっとも信頼できるCA証明書が含まれません。代わりに、getTrustAnchorメソッドを使って、もっとも信頼できるCAのCertificateを取得します。

このクラスの詳細は、PKIXCertPathBuilderResultのAPIドキュメントを参照してください。

例9-2 PKIXアルゴリズムを使った証明書パスの構築例

これは、PKIXアルゴリズムに従って検証される証明書パスの構築例です。例外処理、およびCertStoreの移入用に信頼できるアンカーおよび証明書を生成する場合など、除外されている詳細もあります。

まず、次の例にあるように、CertPathBuilderを生成します。


    CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");

この呼出しは、PKIXアルゴリズムに従って検証されるパスを返すCertPathBuilderオブジェクトを生成します。

次のステップでは、PKIXBuilderParametersオブジェクトを生成します。これは、CertPathBuilderにより使用されるPKIXパラメータの移入に使用されます。


    // Create parameters object, passing it a Set of
    // trust anchors for anchoring the path
    // and a target subject DN.
    X509CertSelector targetConstraints = new X509CertSelector();
    targetConstraints.setSubject("CN=alice,O=xyz,C=us");
    PKIXBuilderParameters params = 
        new PKIXBuilderParameters(trustAnchors, targetConstraints);

次のステップでは、CertPathBuilderが証明書およびCRLの検索に使用するCertStoreを指定します。この例では、証明書およびCRLを使用してCollection CertStoreを移入します。


    CollectionCertStoreParameters ccsp = 
        new CollectionCertStoreParameters(certsAndCrls);
    CertStore store = CertStore.getInstance("Collection", ccsp);
    params.addCertStore(store);

次のステップでは、生成済みの入力パラメータ・セットを使って証明書パスを構築します。


    try {
        PKIXCertPathBuilderResult result = 
            (PKIXCertPathBuilderResult) cpb.build(params);
        CertPath cp = result.getCertPath();
    } catch (CertPathBuilderException cpbe) {
        System.out.println("build failed: " + cpbe.getMessage());
    }

CertPathBuilderは、指定されたパラメータを満たすパスを構築できない場合、CertPathBuilderExceptionをスローします。そうでない場合、検証された証明書パスは、getCertPathメソッドを使ってPKIXCertPathBuilderResultから取得できます。

PKIXCertPathCheckerクラス

PKIXCertPathCheckerクラスは、ユーザーがPKIX CertPathValidatorまたはCertPathBuilder実装を拡張できるようにします。これは、ほとんどのユーザーは理解する必要のない高度な機能です。ただし、PKIXサービス・プロバイダを実装している方は、このセクションをお読み下さい

PKIXCertPathCheckerクラスは、X.509証明書で1つ以上のチェックを実行する抽象クラスです。開発者は、実行時にPKIX CertPathValidatorまたはCertPathBuilder実装を動的に拡張する必要がある場合、PKIXCertPathCheckerクラスの固定実装を作成する必要があります。PKIXCertPathChecker実装が役立つ例のいくつかを次に示します。

  • PKIX CertPathValidatorまたはCertPathBuilder実装によって提供される失効メカニズムが適さない場合。たとえば、PKIXRevocationChecker (JDK 8で導入。PKIXRevocationCheckerクラスを使った証明書の失効ステータスのチェックを参照)を使用して失効メカニズムをより詳細に制御したり、独自のPKIXCertPathCheckerを実装して証明書が失効していないことをチェックしたりできます。

  • ユーザーが重要な非公開の拡張情報を含む証明書を認識したい場合。拡張情報は非公開なので、PKIX CertPathValidatorまたはCertPathBuilder実装によって認識されず、CertPathValidatorExceptionがスローされます。この場合、開発者は重要な非公開の拡張情報を認識して処理するPKIXCertPathCheckerを実装できます。

  • 開発者が、デバッグ時に処理される各証明書についての情報を記録したい、または目的を表示したい場合。

  • ユーザーが特定のポリシー修飾子を持つ証明書を拒否したい場合。

PKIXParametersクラスのsetCertPathCheckersメソッドを使用すると、ユーザーはPKIXCertPathCheckerオブジェクトのListをPKIX CertPathValidatorまたはCertPathBuilder実装に渡すことができます。各PKIXCertPathCheckerオブジェクトは、PKIX CertPathValidatorまたはCertPathBuilder実装によって処理される証明書ごとに、順次呼び出されます。

PKIXCertPathCheckerオブジェクトの生成および使用

PKIXCertPathCheckerクラスには、publicコンストラクタはありません。PKIXCertPathCheckerのインスタンスの生成は実装に固有の問題なので、あえてこのようになっています。たとえば、証明書の失効ステータスのチェックにOCSPを使用するPKIXCertPathChecker実装のコンストラクタは、OCSPサーバーのホスト名およびポートを要求できます。

        PKIXCertPathChecker checker = new OCSPChecker("ocsp.sun.com", 1321);

チェッカのインスタンスが生成されると、PKIXParametersクラスのaddCertPathCheckerメソッドを使って、パラメータとして追加できます。

        params.addCertPathChecker(checker);

また、チェッカのListは、PKIXParametersクラスのsetCertPathCheckersメソッドを使って追加できます。

PKIXCertPathCheckerオブジェクトの実装

PKIXCertPathCheckerクラスは、抽象クラスです。このクラスには4つのメソッド(checkgetSupportedExtensionsinit、およびisForwardCheckingSupported)があり、すべての固定サブクラスはこれらを実装する必要があります。

PKIXCertPathCheckerの実装は、簡単な場合と複雑な場合があります。PKIXCertPathChecker実装には、ステートレスとステートフルがあります。ステートレスな実装では、checkメソッドの連続する呼出しの間で、状態が維持されません。たとえば、特定のポリシー修飾子を含む各証明書を確認するPKIXCertPathCheckerはステートレスです。それに対して、ステートフルな実装では、checkメソッドの連続する呼出しの間で、状態を維持します。通常、ステートフルな実装のcheckメソッドは、証明書パス内の以前の証明書の内容に依存します。たとえば、NameConstraints拡張情報を処理するPKIXCertPathCheckerはステートフルです。

また、サービス・プロバイダ実装によって処理される証明書がPKIXCertPathCheckerに提供される(渡される)順序は、実装がステートフルである場合は特に重要です。証明書は、サービス・プロバイダが使用するアルゴリズムによって逆方向または順方向の順序で渡されます。逆方向とは、証明書がもっとも信頼できるCA (存在する場合)からターゲットの主体へと順序付けられていることを意味します。それに対して順方向とは、証明書がターゲットの主体からもっとも信頼できるCAへと順序付けられていることを意味します。PKIXCertPathChecker実装には、連続した証明書の処理方法を理解できるようにするため、順序を知らせる必要があります。

PKIXCertPathCheckerオブジェクトの初期化

initメソッドは、チェッカの内部状態を初期化します。

        public abstract void init(boolean forward)

すべてのステートフルな実装は、チェッカの内部状態をクリアまたは初期化する必要があります。こうすれば、サービス・プロバイダ実装は、初期化されていない状態のチェッカを呼び出すことができません。また、ステートフルなチェッカは、インスタンスを再度生成しなくても、以降の操作でそれを再利用できます。forwardパラメータは、PKIXCertPathCheckerに渡される証明書の順序を示します。forwardtrueである場合、証明書はターゲットから信頼できるアンカーに渡され、falseの場合、信頼できるアンカーからターゲットに渡されます。

順方向のチェック

isForwardCheckingSupportedメソッドは、PKIXCertPathCheckerが順方向のチェックをサポートするかどうかを示すbooleanを返します。

        public abstract boolean isForwardCheckingSupported()

すべてのPKIXCertPathChecker実装は逆方向のチェックをサポートしている必要がありますPKIXCertPathChecker実装は順方向のチェックをサポートできます

順方向のチェックをサポートすると、パスが構築時にチェックされるので、順方向に構築するCertPathBuilderの効率が向上します。ただし、ステートフルなPKIXCertPathCheckerでは、順方向チェックのサポートが難しいか、または不可能な場合があります。

サポートされる拡張情報

getSupportedExtensionsメソッドは、PKIXCertPathChecker実装がサポートする(つまり、認識し、処理できる) X.509拡張情報の不変のOID StringSetを返します。

        public abstract Set<String> getSupportedExtensions()

拡張情報が処理されない場合、メソッドはnullを返す必要があります。すべての実装は、checkメソッドが処理するOID StringSetを返す必要があります。

CertPathBuilderは、この情報を使って、順方向のチェックをサポートしないPKIXCertPathCheckerで順方向の構築を実行しているときでも、認識されない重要な拡張情報を含む証明書を識別できます。

チェックの実行

次のメソッドは、証明書に対するチェックを実行します。

        public abstract void 
                check(Certificate cert, Collection<String> unresolvedCritExts)
                throws CertPathValidatorException

unresolvedCritExtsパラメータには、OIDのコレクションがStringとして含まれています。これらのOIDは、まだ証明書パスの検証アルゴリズムで解釈されていない証明書内の重要な拡張情報のセットを表します。checkメソッドの固定実装は、unresolvedCritExtsパラメータから処理するすべての重要な拡張情報を削除する必要があります。

証明書がチェックに合格しない場合、CertPathValidatorExceptionがスローされる必要があります。

PKIXCertPathCheckerの複製

PKIXCertPathCheckerクラスは、Cloneableインタフェースを実装します。ステートフルなPKIXCertPathChecker実装はすべて、必要に応じて、cloneメソッドをオーバーライドする必要があります。cloneメソッドのデフォルトの実装は、Object.cloneメソッドを呼び出します。このメソッドは、元のオブジェクトのすべてのフィールドを新しいオブジェクトにコピーすることにより、簡単な複製を実行します。ステートレスな実装は、cloneメソッドをオーバーライドしません。ただし、ステートフルな実装はすべて、デフォルトのcloneメソッドが正しいことを確認し、必要に応じてそれをオーバーライドする必要があります。たとえば、配列内の状態を格納するPKIXCertPathCheckerは、配列を参照するだけではなく、配列のコピーを作成するため、cloneメソッドをオーバーライドする必要があります。

PKIXCertPathCheckerオブジェクトがCloneableである理由は、潜在的な証明書パスが行き詰まったり、障害ポイントに到達した場合、CertPathBuilder実装が効率的に戻り、別のパスを試すことができるようにするためです。この場合、実装は、複製されたオブジェクトを復元することにより、以前のパスの検証状態を復元できます。

例9-3 非公開の拡張情報をチェックするサンプル・コード

これは、ステートレスなPKIXCertPathChecker実装の例です。非公開の拡張情報が証明書に存在するかどうかをチェックし、いくつかの規則に従って処理します。

        import java.security.cert.Certificate;
        import java.security.cert.X509Certificate;
        import java.util.Collection;
        import java.util.Collections;
        import java.util.Set;
        import java.security.cert.PKIXCertPathChecker;
        import java.security.cert.CertPathValidatorException;

        public class MyChecker extends PKIXCertPathChecker {
            private static Set supportedExtensions =
                Collections.singleton("2.16.840.1.113730.1.1");

            /*
             * Initialize checker
             */
            public void init(boolean forward) 
                throws CertPathValidatorException {
                // nothing to initialize
            }

            public Set getSupportedExtensions() {        
                return supportedExtensions;
            }

            public boolean isForwardCheckingSupported() {
                return true;
            }

            /*
             * Check certificate for presence of Netscape's
             * private extension
             * with OID "2.16.840.1.113730.1.1"
             */
            public void check(Certificate cert, 
                              Collection unresolvedCritExts)
                throws CertPathValidatorException 
            {
                X509Certificate xcert = (X509Certificate) cert;
                byte[] ext = 
                    xcert.getExtensionValue("2.16.840.1.113730.1.1");
                if (ext == null)
                    return;

                //
                // process private extension according to some 
                // rules - if check fails, throw a 
                // CertPathValidatorException ...
                // {insert code here}

                // remove extension from collection of unresolved 
                // extensions (if it exists)
                if (unresolvedCritExts != null)
                    unresolvedCritExts.remove("2.16.840.1.113730.1.1");
            }
        }

PKIXサービス・プロバイダ実装によるPKIXCertPathCheckerの使用方法

PKIXCertPathCheckerオブジェクトは、構築または検証アルゴリズムを開始する前に、サービス・プロバイダ実装によって初期化される必要があります。たとえば:

        List<PKIXCertPathChecker> checkers = params.getCertPathCheckers();
        for (PKIXCertPathChecker checker : checkers) {
            checker.init(false);
        }

検証する証明書ごとに、サービス・プロバイダ実装は各PKIXCertPathCheckerオブジェクトのcheckメソッドを順に呼び出し、証明書および残りの解釈されていない重要な拡張情報に渡します。

        for (PKIXCertPathChecker checker : checkers) {
            checker.check(cert, unresolvedCritExts);
        }

checkのどれかがCertPathValidatorExceptionをスローする場合、CertPathValidator実装は、検証手順を終了する必要があります。ただし、CertPathBuilder実装は、単に障害を記録し、引き続きその他の潜在的なパスを探す場合があります。すべてのcheckが成功した場合、サービス・プロバイダ実装は、すべての重要な拡張情報が解釈されていることを確認します。そうでない場合、検証が失敗したとみなされます。たとえば:

        if (unresolvedCritExts != null &&
            !unresolvedCritExts.isEmpty())
        {
            // Note that a CertPathBuilder may have an enclosing
            // try block to catch the exception and continue on error
            throw new CertPathValidatorException
                ("Unrecognized Critical Extension");
        }

前のセクションで説明したように、CertPathBuilder実装は、潜在的な証明書パスが行き詰まったり、障害ポイントに達した場合は、戻る必要があります。ここで戻るというのは、パス内の以前の証明書に戻り、その他の潜在的なパスを探すことを意味します。CertPathBuilder実装がパスの構築中にパスを検証する場合、各PKIXCertPathCheckerの以前の状態を復元する必要があります。これを行うには、各証明書が処理されるに、PKIXCertPathCheckerオブジェクトを複製します。たとえば:

        /* clone checkers */
        List newList = new ArrayList(checkers);
        ListIterator li = newList.listIterator();
        while (li.hasNext()) {   
            PKIXCertPathChecker checker = (PKIXCertPathChecker) li.next();
            li.set(checker.clone());
        }
証明書パス検証でのPKIXCertPathCheckerの使用

PKIXCertPathCheckerを使用して証明書パス検証をカスタマイズすることは、比較的簡単です。

基本の証明書パス検証

まず、証明書パスを検証するコードを考慮します。


Set<TrustAnchor> trustAnchors = getTrustAnchors();
CertPath cp = getCertPath();

PKIXParameters pkixp = new PKIXParameters(trustAnchors);
pkixp.setRevocationEnabled(false);

CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
PKIXCertPathValidatorResult pcpvr =
    (PKIXCertPathValidatorResult)cpv.validate(cp, pkixp);

検証が失敗した場合、validate()メソッドは例外をスローします。

基本のステップは次のとおりです。

  1. CAルート証明書および検証する証明書パスを取得します。
  2. 信頼できるアンカーでPKIXParametersを作成します。
  3. CertPathValidatorを使用して、証明書パスを検証します。

この例では、getTrustAnchors()およびgetCertPath()がCAルート証明書と証明書パスを取得するメソッドです。

この例のgetTrustAnchors()メソッドは、検証に使用したいCAルート証明書を表すTrustAnchorSetを返す必要があります。これは、ファイルから単一のCAルート証明書をロードする1つの簡単な実装です。


public Set<TrustAnchor> getTrustAnchors()
    throws IOException, CertificateException {

  CertificateFactory cf = CertificateFactory.getInstance("X.509");

  X509Certificate c;
  try (InputStream in = new FileInputStream("x509_ca-certificate.cer")) {
    c = (X509Certificate)cf.generateCertificate(in);
  }

  TrustAnchor anchor = new TrustAnchor(c, null);
  return Collections.singleton(anchor);
}

同様に、これは、ファイルから証明書パスをロードするgetCertPath()の簡単な実装です。


public CertPath getCertPath() throws IOException, CertificateException {
  CertificateFactory cf = CertificateFactory.getInstance("X.509");

  CertPath cp;
  try (InputStream in = new FileInputStream("certpath.pkcs7")) {     
    cp = cf.generateCertPath(in, "PKCS7");
  }   
  return cp;
}

PKCS#7では、ファイル内の証明書の特定の順番を必要としないため、このコードは、証明書が検証されるエンティティから始まり、CAルートに戻る順番になっている場合の証明書パス検証にのみ有効です。証明書の順番が正しくない場合、追加の処理が必要です。CertificateFactoryには、この種類の処理に使用できるCollectionを受け付けるgenerateCertPath()メソッドがあります。

PKIXCertPathCheckerへの追加

証明書パス検証をカスタマイズするには、次のようにPKIXCertPathCheckerを追加します。この例では、SimpleCheckerPKIXCertPathCheckerサブクラスです。新しい行をboldで示します。


Set<TrustAnchor> trustAnchors = getTrustAnchors();
CertPath cp = getCertPath();

PKIXParameters pkixp = new PKIXParameters(trustAnchors);
pkixp.setRevocationEnabled(false);

SimpleChecker sc = new SimpleChecker();
pkixp.addCertPathChecker(sc);

CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
PKIXCertPathValidatorResult pcpvr =
    (PKIXCertPathValidatorResult)cpv.validate(cp, pkixp);

SimpleCheckerPKIXCertPathCheckerの基本的なサブクラスです。そのcheck()メソッドは、検証される証明書パス内のすべての証明書に対して呼び出されます。SimpleCheckerAlgorithmConstraints実装を使用して、各証明書の署名アルゴリズムと公開キーを調査します。


import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive;
import java.security.Key;
import java.security.cert.*;
import java.util.*;

public class SimpleChecker extends PKIXCertPathChecker {
  private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
      EnumSet.of(CryptoPrimitive.SIGNATURE);
  
  public void init(boolean forward) throws CertPathValidatorException {}
  
  public boolean isForwardCheckingSupported() { return true; }
  
  public Set<String> getSupportedExtensions() { return null; }
  
  public void check(Certificate cert,
      Collection<String> unresolvedCritExts)
      throws CertPathValidatorException {
    X509Certificate c = (X509Certificate)cert;
    String sa = c.getSigAlgName();
    Key key = c.getPublicKey();
    
    AlgorithmConstraints constraints = new SimpleConstraints();
    
    if (constraints.permits(SIGNATURE_PRIMITIVE_SET, sa, null) == false)
      throw new CertPathValidatorException("Forbidden algorithm: " + sa);

    if (constraints.permits(SIGNATURE_PRIMITIVE_SET, key) == false)
      throw new CertPathValidatorException("Forbidden key: " + key);
  }
}

最後に、SimpleConstraintsは、RSA 2048を必要とするAlgorithmConstraints実装です。


import java.security.AlgorithmConstraints;
import java.security.AlgorithmParameters;
import java.security.CryptoPrimitive;
import java.security.Key;
import java.security.interfaces.RSAKey;
import java.util.Set;

public class SimpleConstraints implements AlgorithmConstraints {
  public boolean permits(Set<CryptoPrimitive> primitives,
      String algorithm, AlgorithmParameters parameters) {
    return permits(primitives, algorithm, null, parameters);
  }

  public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
    return permits(primitives, null, key, null);
  }
  
  public boolean permits(Set<CryptoPrimitive> primitives,
      String algorithm, Key key, AlgorithmParameters parameters) {
    if (algorithm == null) algorithm = key.getAlgorithm();
    
    if (algorithm.indexOf("RSA") == -1) return false;
    
    if (key != null) {
      RSAKey rsaKey = (RSAKey)key;
      int size = rsaKey.getModulus().bitLength();
      if (size < 2048) return false;
    }

    return true;
  }
}
PKIXRevocationCheckerクラスを使った証明書の失効ステータスのチェック

PKIXRevocationCheckerのインスタンスは、オンライン証明書ステータス・プロトコル(OCSP)または証明書の失効リスト(CRL)を使って証明書の失効ステータスをチェックします。

PKIXRevocationChecker (JDK 8で導入)は、PKIXCertPathCheckerのサブクラスであり、PKIXアルゴリズムを使用して証明書の失効ステータスをチェックします。

PKIXRevocationCheckerのインスタンスは、オンライン証明書ステータス・プロトコル(OCSP)または証明書の失効リスト(CRL)を使って証明書の失効ステータスをチェックします。OCSPは、RFC 2560に記述されている、証明書のステータスを判定するためのネットワーク・プロトコルです。CRLは、失効した証明書を識別するタイム・スタンプ付きのリストです。RFC 5280には、CRLを使って証明書の失効ステータスを判定するためのアルゴリズムが記述されています。

PKIX CertPathValidatorおよびCertPathBuilderの各インスタンスは、デフォルトで有効になるデフォルトの失効実装を提供します。その実装で使用される失効設定をより詳細に制御する必要がある場合は、PKIXRevocationCheckerクラスを使用します。

PKIXRevocationCheckerクラスを使って証明書パスの失効ステータスをチェックするには、これらの一般的なステップを実行します。

  1. PKIX CertPathValidatorまたはCertPathBuilderインスタンスのgetRevocationCheckerメソッドを呼び出して、PKIXRevocationCheckerインスタンスを取得します。

  2. PKIXRevocationCheckerクラスに含まれるメソッドを使って、証明書の失効に固有の追加パラメータおよびオプションを設定します。これらのメソッドには、OCSP応答者の場所を特定するURIを設定するsetOCSPResponder(URI)(ただし、通常このURIは証明書に含まれているため、設定する必要はありません)と、失効オプションを設定するsetOptions(Set<PKIXRevocationChecker.Option>)が含まれています。PKIXRevocationChecker.Optionは、次のオプションを指定するために使用される列挙型です。

    • ONLY_END_ENTITY: エンドエンティティ証明書の失効ステータスのみをチェックします。
    • PREFER_CRLS: デフォルトでは、OCSPが失効ステータスをチェックするための推奨メカニズムであり、CRLは代替メカニズムです。この設定を切り替えるには、このオプションを使用します。
    • SOFT_FAIL: ネットワーク障害を無視します。
  3. PKIXRevocationCheckerのインスタンスを取得したら、addCertPathCheckerまたはsetCertPathCheckersメソッドを使用してPKIXParametersまたはPKIXBuilderParametersオブジェクトにそれを追加します。

  4. PKIX CertPathValidatorまたはCertPathBuilderインスタンスのどちらを使用するかに応じて、これらのステップのいずれかを実行します。

    • PKIX CertPathValidatorインスタンスを使用する場合は、検証する証明書パスと、失効チェッカを含むPKIXParametersオブジェクトを引数として指定して、validateメソッドを呼び出します。

    • PKIX CertPathBuilderインスタンスを使用する場合は、失効チェッカを含むPKIXBuilderParametersオブジェクトを引数として指定して、buildメソッドを呼び出します。

  5. 検証する証明書パスと、失効チェッカを含むPKIXParametersまたはPKIXBuilderParametersオブジェクトを引数として指定して、PKIX CertPathValidatorまたはCertPathBuilderインスタンスのvalidateメソッドを呼び出します。

次の抜粋は、証明書パスに含まれる証明書の失効ステータスをチェックします。CertPathオブジェクトpathは証明書パスです。paramsPKIXParameters型のオブジェクトです。


    CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
    PKIXRevocationChecker rc = (PKIXRevocationChecker)cpv.getRevocationChecker();
    rc.setOptions(EnumSet.of(Option.SOFT_FAIL));
    params.addCertPathChecker(rc);
    params.setRevocationEnabled(false);
    CertPathValidatorResult res = cpv.validate(path, params);

この抜粋では、SOFT_FAILオプションによって、失効チェッカが失効ステータスをチェックするときにネットワーク障害(OCSPサーバーへの接続確立の失敗など)が無視されます。

サービス・プロバイダの実装

上級プログラマは、証明書パス・サービス実装を提供する独自のプロバイダ・パッケージを作成できます。

この項は、読者がJava暗号化アーキテクチャ(JCA)リファレンス・ガイドを読んでいることを前提としています。

Java Certification Path APIでは、次のエンジン・クラスが定義されています。

  • CertPathValidator - 証明書パスの検証に使用される

  • CertPathBuilder - 証明書パスの構築に使用される

  • CertStore - リポジトリから証明書とCRLを取得するために使用される

さらに、既存のCertificateFactoryエンジン・クラスは、証明書パスの生成をサポートしています。

エンジン・クラスが提供するアプリケーション・インタフェースは、「Service Provider Interface」(SPI)として実装されます。各SPIクラスの名前は、対応するエンジン・クラス名のあとに「Spi」を追加した名前になります。たとえば、CertPathValidatorエンジン・クラスに対応するSPIクラスは、CertPathValidatorSpiクラスです。各SPIクラスは、抽象クラスです。個々のアルゴリズムまたは型について、特定の型のサービスの実装を提供するには、プロバイダは対応するSPIクラスをサブクラス化して、すべての抽象メソッドの実装を提供する必要があります。たとえば、CertStoreクラスは、証明書およびCRLをリポジトリから取得する機能を利用できるようにします。CertStoreSpiサブクラスで提供される実際の実装は、LDAPなど、特定の型の証明書リポジトリのための実装です。

プロバイダの実装および統合までのステップ

証明書パス・サービスのためにプロバイダを実装および統合する場合は、特定の情報が提供されていることを確認する必要があります。

開発者は、プロバイダの実装および統合までのステップに従う必要があります。次に、特定のステップで従う規則をさらにいくつか示します。

ステップ3: プロバイダのサブクラスである「マスター・クラス」の記述

ステップ3: プロバイダのサブクラスであるマスター・クラスの記述では、これらが、証明書パス・サービス用に定義する必要があるプロパティです。ここではアルゴリズム名はalgNameに置き換えられ、certstore型はstoreTypeに置き換えられています。

  • CertPathValidator.algName

  • CertPathBuilder.algName

  • CertStore.storeType

algNameおよびstoreTypeに対して定義されている標準名は、Javaセキュリティ標準アルゴリズム名を参照してください。各プロパティの値は、指定されたアルゴリズムを実装するクラスの完全修飾名、またはcertstore型である必要があります。つまり、クラス名のあとにピリオドとパッケージ名が記述されていなければなりません。たとえば、プロバイダは、次のようにしてCertPathValidator.PKIXプロパティを設定し、値sun.security.provider.certpath.PKIXCertPathValidatorを保持します。


put("CertPathValidator.PKIX", "sun.security.provider.certpath.PKIXCertPathValidator")

さらに、サービス属性を証明書パス・サービス用に定義できます。これらの属性は、サービス・プロバイダを選択するためのフィルタとして使用できます。標準のサービス属性の定義については、付録Aを参照してください。たとえば、プロバイダがValidationAlgorithmサービス属性をPKIX検証アルゴリズムを定義する仕様またはRFCの名前に設定している場合があります。


put("CertPathValidator.PKIX ValidationAlgorithm", "RFC5280");

ステップ11: プロバイダおよびそのサポート対象サービスのドキュメント化

ステップ12: プロバイダおよびそのサポート対象サービスのドキュメント化では、証明書パス・サービス・プロバイダは、SPIごとに次の情報をドキュメント化する必要があります。

証明書ファクトリ

プロバイダは、ファクトリが作成できる証明書パスの種類(および必要に応じてパス内の証明書のバージョン番号)をドキュメント化する必要があります。プロバイダは、内容だけでなく、証明書パスの証明書の順序を記述する必要があります。

プロバイダは、サポートされているエンコード形式のリストをドキュメント化する必要があります。クライアントはgetCertPathEncodingsメソッドを呼び出してそれらを要求できるので、技術的にはこの作業は必要ありません。ただし、ドキュメントには各エンコード形式について詳細に記述し、該当する場合は、標準について言及する必要があります。

証明書パスの検証

プロバイダは、検証する証明書パスの種類など、CertPathValidator実装についての関連情報をドキュメント化する必要があります。特に、PKIX CertPathValidator実装は、次の情報をドキュメント化する必要があります。

  • 準拠したRFCまたは仕様。
  • 証明書が取り消されていないことをチェックするために使用するメカニズム。
  • 認識するオプションの証明書またはCRL拡張機能、およびそれらを処理する方法。

証明書パスの構築

プロバイダは、作成する証明書パスの種類、およびそれらのパスが検証されているかどうかなど、CertPathBuilder実装の関連情報をドキュメント化する必要があります。特に、PKIX CertPathBuilder実装は、次の情報をドキュメント化する必要があります。

  • 準拠したRFCまたは仕様。
  • 証明書が取り消されていないことをチェックするために使用するメカニズム。
  • 認識するオプションの証明書またはCRL拡張機能、およびそれらを処理する方法。
  • 証明書パスの検索に使用するアルゴリズムの詳細。例: 深さ優先、幅優先、順方向(つまり、ターゲットから信頼できるアンカーへ)、逆方向(つまり、信頼できるアンカーからターゲットへ)。
  • 潜在的な証明書の選択およびソートに使用されるアルゴリズム。たとえば、パス内に次の証明書の候補になりうる2つの証明書がある場合、一方を先に選択するためにどの条件を使用するか。証明書の拒否にどの条件を使用するか。
  • 該当する場合、別のパスに戻る、または別のパスを構築する際に使用するアルゴリズム(つまり、潜在的なパスが制約に適合しない場合)。
  • テスト済みのCertStore実装の型。実装は、どのCertStore型でも動作するように設計されている必要があるが、それでもなおこの情報が役立つことがある。

すべてのCertPathBuilder実装は、潜在的なパスの構築に関する問題を分析および修正するため、付加的なデバッグ・サポートを提供する必要があります。このデバッグ情報へのアクセス方法の詳細については、ドキュメント化されている必要があります。

証明書/CRLストア

プロバイダは、CertStoreによって取得される証明書およびCRLの種類(および必要に応じてバージョン番号)をドキュメント化する必要があります。

また、プロバイダは、CertStore実装に関するすべての情報 (使用されるプロトコルまたはサポートされる形式など)をドキュメント化する必要があります。たとえば、LDAP CertStore実装では、どのバージョンのLDAPがサポートされているのか、およびどの標準属性が証明書およびCRLの検索に使用されるのかを記述する必要があります。また、実装が結果をキャッシュするかどうか、およびその期間(つまりリフレッシュの条件)をドキュメント化する必要があります。

実装が、特定の順序で証明書およびCRLを返す場合、ソート・アルゴリズムを記述する必要があります。また、実装は、すべての追加またはデフォルトの初期化パラメータを記述する必要があります。最後に、実装は証明書およびCRLの検索にCertSelectorまたはCRLSelectorオブジェクトの情報を使用するかどうか、およびその方法をドキュメント化する必要があります。

サービスの相互依存性

証明書パス・サービス実装におけるアルゴリズムの相互依存の一般的な種類を示します。

次に、証明書パス・サービス実装におけるアルゴリズムの相互依存の一般的な種類を示します。

  • 証明書パスの検証および署名アルゴリズム

    CertPathValidator実装は、各証明書のデジタル署名を検証するため、署名アルゴリズムの使用を要求する場合があります。PKIXParametersクラスのsetSigProviderメソッドにより、ユーザーは特定のSignatureプロバイダを指定できます。

  • 証明書パスの構築および証明書ファクトリ

    CertPathBuilder実装は、証明書のリストから証明書パスを生成するため、CertificateFactoryを使用する場合があります。

  • CertStoresおよび証明書ファクトリ

    CertStore実装は、証明書およびCRLをエンコードから生成するため、CertificateFactoryを使用することがあります。たとえば、LDAP CertStore実装は、X.509 CertificateFactoryを使用して、ASN.1エンコード形式からX.509証明書およびCRLを生成します。 

証明書パス・パラメータ仕様のインタフェース

Certification Path APIには、パラメータの透過的な仕様を表すCertPathParametersおよびCertStoreParametersという2つのインタフェースが含まれています。

CertPathParametersインタフェースには、PKIXParametersおよびPKIXBuilderParametersクラスという2つの実装が含まれています。PKIX証明書パスの検証およびアルゴリズム・パラメータを使って作業する場合、これらのクラスを利用できます。アルゴリズムごとにパラメータが必要な場合は、そのアルゴリズムに独自のCertPathParameters実装を提供する必要があります。

CertStoreParametersインタフェースには、LDAPCertStoreParametersおよびCollectionCertStoreParametersクラスという2つの実装が含まれています。これらのクラスは、それぞれLDAPおよびCollection CertStore実装で別々に使用されます。リポジトリ型ごとにパラメータが必要な場合は、その型に独自のCertStoreParameters実装を提供する必要があります。

CertPathParametersおよびCertStoreParametersインタフェースは、それぞれ実装がオーバーライドする必要のあるcloneメソッドを定義します。標準的な実装は、オブジェクトの「ディープ」コピーを実行し、それ以降コピーに対して行われる変更が元のオブジェクトに影響しないように(逆の場合も同様)します。ただし、これは、CertStoreParametersの実装の絶対的な要件ではありません。しかし、CertStoreParametersに含まれるパラメータへの参照を保持する必要があるアプリケーションでは、cloneのシャロー・コピー実装の方が適切です。たとえば、CertStore.getInstanceは指定されたCertStoreParametersの複製を作成するので、アプリケーションはガベージ・コレクション・メカニズムを待つのではなく、シャロー・コピーcloneを使用して特定のCertStore初期化パラメータのリソースへの参照を維持し、後でリリースできます。CertStoreがその他のスレッドによって使用されていることがあるので、この操作は細心の注意を払って行う必要があります。

証明書パスの結果の仕様インタフェース

Certification Path APIには、結果の透過的な仕様を表すCertPathValidatorResultおよびCertPathBuilderResultという2つのインタフェースが含まれています。

各インタフェースの実装には、それぞれPKIXCertPathValidatorResultおよびPKIXCertPathBuilderResultクラスが含まれます。PKIX証明書パス・サービス・プロバイダを実装する場合、これらのクラスを使用できます。アルゴリズムごとに証明書パスの結果が必要な場合は、そのアルゴリズムに独自のCertPathValidatorResultまたはCertPathBuilderResult実装を提供する必要があります。

CertPathValidatorまたはCertPathBuilderのPKIX実装では、デバッグ・トレースなど、PKIXCertPathValidatorResultまたはPKIXCertPathBuilderResultの追加情報を格納することが有用な場合があります。この場合、実装は、関連情報を取得するメソッドを持つ、適切な結果クラスのサブクラスを実装する必要があります。これらのクラスは、プロバイダ・クラスとともに(たとえば、プロバイダJARファイルの一部として)提供される必要があります。

証明書パスの例外クラス

Certification Path APIには、エラーを処理する例外クラスのセットが含まれています。CertPathValidatorException、CertPathBuilderException、およびCertStoreExceptionは、GeneralSecurityExceptionのサブクラスです。

サービス・プロバイダ実装では、これらのクラスの拡張が必要になる場合があります。

たとえば、CertPathBuilder実装は、CertPathBuilderExceptionがスローされるときに、デバッグ・トレースなどの追加情報を提供します。実装は、この情報を保持するCertPathBuilderExceptionのサブクラスをスローします。同様に、CertStore実装は、CertStoreException のサブクラスをスローすることにより障害が発生した場合、追加情報を提供できます。また、CertPathValidator実装の特定の障害モードについて記述するため、CertPathValidatorExceptionのサブクラスを実装することもできます。

どちらの場合も、新しい例外クラスはプロバイダ・クラスとともに(たとえば、プロバイダJARファイルの一部として)提供される必要があります。各プロバイダは、例外サブクラスをドキュメント化する必要があります。

付録A: 標準名

Java Certification Path APIでは、証明書パスの検証アルゴリズム、エンコードおよび証明書ストレージの型について、標準名のセットを必要とし、それらを使用します。

以前にこの付録Aおよびその他のセキュリティ仕様(JCA/JSSE/など)にあった標準名は、Javaセキュリティ標準アルゴリズム名にまとめられました。特定のプロバイダの情報は、JDKプロバイダにあります。

サービス・プロバイダは、標準名のドキュメントに記述されていない独自のアルゴリズムまたは非標準のアルゴリズムに新しい名前を定義することもできます。ただし、名前の衝突を防止するため、プロバイダの組織のインターネット・ドメイン名を逆にしたもの(com.sun.MyCertPathValidatorなど)を名前の前に付けることをお薦めします。

付録B: SUNプロバイダでのCertPath実装

「SUN」プロバイダは、次の標準アルゴリズム、型、およびエンコードをサポートしています。

  • CertificateFactory: X.509 CertPath型とPKCS7およびPkiPathエンコード
  • CertPathValidator: PKIXアルゴリズム
  • CertPathBuilder: PKIXアルゴリズム
  • CertStore: Collection CertStore

次に、これらの各サービス・プロバイダ・インタフェースの実装について説明します:

CertificateFactory

CertificateFactoryエンジン・クラス用のSUNプロバイダでは、X.509 CertPathオブジェクトの生成がサポートされています。PKCS7およびPkiPathエンコードがサポートされます。PKCS#7実装は、RFC 2315のサブセットをサポートします(SignedData ContentInfo型だけがサポートされる)。CertPathの証明書は、順方向に(ターゲットから信頼できるアンカーへ)順序付けされます。CertPathの各証明書はjava.security.cert.X509Certificate型であり、バージョン1、2および3がサポートされています。

CertPathValidator

「SUN」プロバイダは、CertPathValidatorエンジン・クラスのPKIX実装を提供します。この実装は、X 509型のCertPathを検証し、RFC 5280: PKIX証明書およびCRLプロファイルで定義されている証明書パス検証アルゴリズムを実装します。この実装では、ValidationAlgorithmサービス属性はRFC5280に設定されます。

弱い暗号化アルゴリズムは、jdk.certpath.disabledAlgorithmsセキュリティ・プロパティを使用して、SUNプロバイダで無効にできます。このプロパティの説明と例は、付録E: 暗号化アルゴリズムの無効化を参照してください。

PKIX証明書とCRLプロファイルには、多くのオプション機能があります。「SUN」プロバイダは、ポリシー・マッピング、Authority Information AccessおよびCRL配布ポイント証明書拡張機能、Issuing Distribution Point CRL拡張機能、原因コードおよびCertificate Issuer CRLエントリ拡張機能のサポートを実装しています。Freshest CRLまたはSubject Information Access証明書拡張機能のサポートは実装していません。また、Freshest CRLおよびDelta CRL Indicator CRL拡張機能とInvalidity DateおよびHold Instruction Code CRLエントリ拡張機能のサポートは含まれません。

実装は、PKIX証明書とCRLプロファイルのセクション6.3に準拠しているCRL失効チェック・メカニズムをサポートします。OCSP (RFC 2560)も、現在、組込みの失効チェック・メカニズムとしてサポートされています。実装と構成、およびCRLとどのように連携するかの詳細は、付録C: OCSPサポートを参照してください。

この実装は、TrustAnchorクラスのnameConstraintsパラメータをサポートしないため、このパラメータが指定されると、validateメソッドによりInvalidAlgorithmParameterExceptionがスローされます。

CertPathBuilder

「SUN」プロバイダは、CertPathBuilderエンジン・クラスのPKIX実装を提供します。実装は、X.509型のCertPathを構築します。各CertPathRFC 5280: PKIX Certificate and CRL Profileに定義されているPKIXアルゴリズムに従って検証されます。この実装では、ValidationAlgorithmサービス属性はRFC5280に設定されます。

この実装では、PKIXBuilderParametersオブジェクトのtargetConstraintsパラメータがX509CertSelectorのインスタンスで、主体の条件がnull以外の値に設定されていることが必要です。そうでない場合、buildメソッドによりInvalidAlgorithmParameterExceptionがスローされます。

実装は、深さ優先アルゴリズムを使って、順方向にCertPathオブジェクトを構築します。潜在的なパスが無効であるか、またはPKIXBuilderParameters maxPathLengthパラメータを超えていると判定されると、前の状態に戻って代替パスを試みます。

パスの検証は、CertPathValidator実装と同じ方法で実行されます。実装は、プロセスの早い段階で無効なパスを削除するために、パスの構築時にほとんどのパスを検証します。順方向に順序付けされている証明書で実行できない検証チェックは延期され、パスが構築されてから(アプリケーションに返される前に)そのパス上で実行されます。

CertPathValidatorと同様に、jdk.certpath.disabledAlgorithmsセキュリティ・プロパティを使用して、安全とみなされない暗号化アルゴリズムを除外できます。

候補となる証明書が2つ以上検出され、指定された制約を満たすパスが見つかる可能性がある場合、実装では次の条件で、証明書の優先順位が設定されます(次の例では、TrustAnchorの識別名"ou=D,ou=C,o=B,c=A"が指定されていると仮定)。

  1. 証明書の発行者DNが、指定されたTrustAnchorのうち1つのDNと一致(例: issuerDN = "ou=D,ou=C,o=B,c=A")。
  2. 証明書の発行者DNがTrustAnchorのうち1つのDNの子孫で、アンカーに近いほうから順に順序付けられている(例: issuerDN = "ou=E,ou=D,ou=C,o=B,c=A")。
  3. 証明書の発行者DNがTrustAnchorのうち1つのDNの祖先で、アンカーに近いほうから順に順序付けられている(例: issuerDN = "ou=C,o=B,c=A")。
  4. 証明書の発行者DNがTrustAnchorのうち1つの同じ名前空間内にあり、アンカーに近いほうから順に順序付けられている(例: issuerDN = "ou=G,ou=C,o=B,c=A")。
  5. 証明書の発行者DNが、証明書の主体DNの祖先で、主体に近いほうから順に順序付けられている。

これらのあとには、どの条件も満たさない証明書が続きます。

この実装は、このリリースの「SUN」プロバイダに含まれるLDAPおよびCollection CertStore実装でテストされています。

デバッグのサポートは、java.security.debugプロパティをcertpathに設定すると有効になります。たとえば:

java -Djava.security.debug=certpath BuildCertPath

こうすると、追加のデバッグ情報が標準エラーに出力されます。

Collection CertStore

SUNプロバイダでは、CertStoreエンジン・クラスのCollection実装がサポートされています。

Collection CertStore実装は、java.security.cert.Certificateまたはjava.security.cert.CRLのインスタンスであるすべてのオブジェクトを保持できます。

証明書およびCRLは、特定の順序で返されることはなく、複製を含みません。

CRL配布ポイント拡張機能のサポート

CRL配布ポイント拡張機能に対して、サポートが提供されます。これは、デフォルトでは互換性を維持するため無効になっています。システム・プロパティcom.sun.security.enableCRLDPの値をtrueに設定すると、これが有効になります。

trueに設定した場合、OracleのPKIX実装は、指定されるCertStoresに加えて証明書のCRL配布ポイント拡張機能の情報を使用して、CRLを検索します。ただし、配布ポイントがX.500識別名、またはldap、httpまたはftp型のURIである必要があります。

ノート:

ネットワークとファイアウォールの設定によっては、ネットワーキング・プロキシ・サーバーも構成する必要がある場合があります。

Authority Information Access (AIA)拡張機能のサポート

Authority Information Access拡張機能のcaIssuersアクセス・メソッドに対して、サポートが提供されます。これは、デフォルトでは互換性を維持するため無効になっています。システム・プロパティcom.sun.security.enableAIAcaIssuersの値をtrueに設定すると、これが有効になります。

trueに設定した場合、OracleのCertPathBuilder PKIX実装は、指定されるCertStoreに加えて証明書のAIA拡張機能の情報を使用して、発行するCA証明書を検索します。ただし、それがldap、httpまたはftp型のURIである必要があります。

ノート:

ネットワークとファイアウォールの設定によっては、ネットワーキング・プロキシ・サーバーも構成する必要がある場合があります。

CRLの取得の最大ネットワーク接続タイムアウト

システム・プロパティcom.sun.security.crl.timeoutによってCRLの取得の最大接続タイムアウトを秒単位で設定します。このプロパティが設定されていないか、負の値の場合は、デフォルト値の15秒に設定されます。値0は、無限タイムアウトを意味します。

付録C: OCSPサポート

RFC 2560に定義されているOCSP (On-Line Certificate Status Protocol)のクライアント側サポートが提供されています。

OCSPチェックは、次の5つのセキュリティ・プロパティで制御されます。
プロパティ名 説明
ocsp.enable このプロパティの値は、trueまたはfalseになる。trueの場合、OCSPチェックは証明書失効チェックの実行中に有効になる。falseまたは設定されていない場合、OCSPチェックは無効になる。
ocsp.responderURL このプロパティの値は、OCSP応答者の場所を特定するURLである。次に例を示します

ocsp.responderURL=http://ocsp.example.net:80

デフォルトでは、OCSP応答者の場所は、検証される証明書から暗黙的に決定される。RFC 5280に定義されているAuthority Information Access拡張機能が証明書にない場合、またはオーバーライドが必要な場合に、このプロパティが使用される。

ocsp.responderCertSubjectName このプロパティの値は、OCSP応答者の証明書の主体名である。次に例を示します

ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp"

デフォルトでは、OCSP応答者の証明書は、検証される証明書の発行者のものである。このプロパティは、デフォルトが適用されない場合に、OCSP応答者の証明書を特定する。この値はRFC 2253で定義された文字列の識別名で、証明書パスの検証中に取得した証明書セットの中から証明書を特定する。サブジェクト名だけでは証明書を一意に特定できない場合は、ocsp.responderCertIssuerNameocsp.responderCertSerialNumberの両方のプロパティを代わりに使用する必要がある。このプロパティが設定されている場合は、この2つのプロパティは無視される。

ocsp.responderCertIssuerName このプロパティの値は、OCSP応答者の証明書の発行者名である。次に例を示します

ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"

デフォルトでは、OCSP応答者の証明書は、検証される証明書の発行者のものである。このプロパティは、デフォルトが適用されない場合に、OCSP応答者の証明書を特定する。この値はRFC 2253で定義された文字列の識別名で、証明書パスの検証中に取得した証明書セットの中から証明書を特定する。このプロパティが設定されている場合、ocsp.responderCertSerialNumberプロパティも設定されている必要がある。ocsp.responderCertSubjectNameプロパティが設定されている場合、このプロパティは無視される。

ocsp.responderCertSerialNumber このプロパティの値は、OCSP応答者の証明書のシリアル番号である。次に例を示す

ocsp.responderCertSerialNumber=2A:FF:00

デフォルトでは、OCSP応答者の証明書は、検証される証明書の発行者のものである。このプロパティは、デフォルトが適用されない場合に、OCSP応答者の証明書を特定する。この値は16進数の文字列(コロンまたはスペースで区切られている)で、証明書パスの検証中に取得した証明書セットの中から証明書を特定する。このプロパティが設定されている場合、ocsp.responderCertIssuerNameプロパティも設定されている必要がある。ocsp.responderCertSubjectNameプロパティが設定されている場合、このプロパティは無視される。

これらのプロパティは、Javaランタイムの<java_home>/conf/security/java.securityファイル内で静的に設定されるか、またはjava.security.Security.setProperty()メソッドを使用して動的に設定されます。

デフォルトでは、OCSPチェックは有効ではありません。ocsp.enableプロパティをtrueに設定すると有効になります。その他のプロパティは、オプションで使用できます。OCSPチェックは、失効チェックも有効になっている場合にのみ有効になります。失効チェックは、PKIXParameters.setRevocationEnabled()メソッドを使用して有効にできます。

OCSPチェックは、失効チェック中に証明書失効リスト(CRL)と連動して機能します。次に、OCSPとCRLがどのように影響し合うかをまとめます。CRLでのフェイルオーバーは、OCSPに問題が発生した場合にかぎり、発生します。OCSP応答者が、証明書が取り消されたことまたは取り消されていないことを確認した場合は、フェイルオーバーは発生しません。

PKIXParameters RevocationEnabled (default=true) ocsp.enable (default=false) 動作
true true OCSPを使用した失効チェック、CRLを使用したフェイルオーバー
true false CRLを使用した失効チェックのみ
false true 失効チェックなし
false false 失効チェックなし

最大許容クロック・スキュー

ネットワークが低速であるか、システム・クロックが一定時間オフになっているために、失効チェック中に接続障害が発生する場合があります。システム・プロパティcom.sun.security.ocsp.clockskewを使用して、失効チェックに使用される最大許容クロック・スキュー(レスポンス時間とローカル時間の時間差)を秒単位で設定します。このプロパティが設定されていないか、負の値の場合は、デフォルト値の900秒(15分)に設定されます。

付録D: JdkLDAPプロバイダでのCertPath実装

JdkLDAPプロバイダでは、CertStoreエンジン・クラスのLDAP実装がサポートされています。

LDAP CertStore

LDAP CertStore実装は、RFC 2587で定義されているLDAPスキーマを使って、証明書およびCRLをLDAPディレクトリから取得します。

LDAPSchemaサービス属性は「RFC2587」に設定されます。

実装は、主体の値、発行者、およびX509CertSelectorで指定されているbasicConstraints選択条件によって、証明書を別の位置からフェッチします。実装は、次の操作をできるだけ多く実行します。

  1. Subject non-null, basicConstraints <= -1

    主体DNの「userCertificate」属性で証明書を検索します。

  2. Subject non-null, basicConstraints >= -1

    主体DNの「crossCertificatePair」属性の順方向の要素内にあり、かつ主体の「caCertificate」属性内にある証明書を検索します。

  3. Issuer non-null, basicConstraints >= -1

    発行者DNの「crossCertificatePair」属性の逆方向要素内にあり、かつ発行者DNの「caCertificate」属性内にある証明書を検索します。

どの場合も、証明書は検索結果のコレクションに追加する前に、X509CertSelector.match()を使ってチェックされます。

上に指定した条件のどれも当てはまらない場合は、指定された条件では証明書をフェッチできなかったことを示す例外がスローされます。1つ以上の条件が適用されたとしても、ディレクトリに証明書がない場合、返されるCollectionは空のままであることに注意してください。

実装は、X509CRLSelectorクラスのsetCertificateCheckingaddIssuerName、またはsetIssuerNamesメソッドで指定された発行者DNからCRLをフェッチします。いずれかのメソッドを使って発行者DNを指定しないと、実装により、指定された基準ではCRLをフェッチできなかったことを示す例外がスローされます。それ以外の場合、CRLは次のように検索されます。

  1. 最初に、実装により発行者名のリストが作成されます。setCertificateCheckingメソッドに証明書が指定されている場合、その証明書の発行者が使用されます。それ以外の場合、addIssuerNameまたはsetIssuerNamesメソッドで指定された発行者名が使用されます。

  2. 次に、発行者名のリストに対して反復処理が行われます。これは、発行者名ごとに、まず発行者のauthorityRevocationList属性内を検索し、一致するCRLが見つからなかった場合は、発行者のcertificateRevocationList属性内を検索します。ただし、setCertificateCheckingメソッドに指定された証明書から発行者名を取得した場合は例外であり、指定された証明書がCA証明書である場合は、発行者のauthorityRevocationList属性のみをチェックします。

  3. すべてのCRLは検索結果のコレクションに追加する前に、X509CRLSelector.match()を使ってチェックされます。

  4. 選択基準を満たすCRLが見つからない場合、空のCollectionが返されます。

キャッシュ

デフォルトでは、各LDAP CertStoreインスタンスは、検索を最大30秒キャッシュします。キャッシュの有効期間は、システム・プロパティsun.security.certpath.ldap.cache.lifetimeの値を秒単位で設定することで変更できます。値を0にすると、キャッシュは完全に無効になります。-1にすると、有効期間が無期限になります。

付録E: 暗号化アルゴリズムの無効化

jdk.certpath.disabledAlgorithmsセキュリティ・プロパティには、弱いか壊れているとみなされた暗号化アルゴリズムおよびキー・サイズ制約のリストが含まれています。これらのアルゴリズムまたはキー・サイズのいずれかを含む証明書およびその他のデータ(CRL、OCSPResponses)は、証明書パスの構築および検証中にブロックされます。このプロパティは、OracleのPKIX実装によって使用されます。他の実装では、検証および使用されない場合があります。

jdk.certpath.disabledAlgorithmsセキュリティ・プロパティの正確な構文は、java.securityファイルで示されています。Java SE 9での、このプロパティのデフォルト値は次のとおりです。
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
    RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
この構文の説明は次のとおりです。
MD2
MD2ベースのアルゴリズムはブロックされます。

たとえば、MD2withRSA署名アルゴリズムを使用して署名された証明書、CRLまたはOCSPResponseです。

MD5
MD5ベースのアルゴリズムはブロックされます。

たとえば、MD5withRSA署名アルゴリズムを使用して署名された証明書、CRLまたはOCSPResponseです。

SHA1 jdkCA & usage TLSServer
cacertsキーストアに事前インストール済の信頼できるアンカーに連鎖する、TLSサーバーの認証に使用されるすべてのSHA1証明書です。JEP 288を参照してください。
RSA keySize < 1024
1024ビットより小さいRSAキーはブロックされます。

たとえば、768ビットのRSA公開キーを使用する証明書です。

DSA keySize < 1024
1024ビットより小さいDSAキーはブロックされます。

たとえば、512ビットのDSA公開キーを使用する証明書です。

EC keySize < 224
224ビットより小さいECキーはブロックされます。

たとえば、160ビットのEC公開キーを使用する証明書です。

管理者またはユーザーは、その他のセキュリティ要件に対応するためにjdk.certpath.disabledAlgorithmsプロパティの値を変更できます。ただし、現在のアルゴリズムまたはキー・サイズを削除することはお薦めできません。

ノート:

このセキュリティ・プロパティで指定されるアルゴリズム制限は、トラスト・アンカーまたは自己署名証明書には適用されません。