10 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つの条件のいずれかに該当する、経験ある開発者を対象にしています。
-
証明書パスを構築または検証する、セキュリティ保護されたアプリケーションを設計する人
-
証明書パスを構築または検証するためのサービス・プロバイダ実装を記述する人
このドキュメントは、暗号化サービス・プロバイダをすでに読んでいることが前提となっています。
公開キー証明書の概要
公開キー・アプリケーションおよびシステムのユーザーは、主体の公開キーが本物であること、つまり、関連する秘密キーが主体によって所有されていることを確信している必要があります。公開キー証明書は、この信頼を確立するのに使用されます。
公開キー(またはアイデンティティ)証明書は、アイデンティティへの公開キーのバインディングです。アイデンティティは、別のエンティティ(多くの場合、証明書発行局(CA)と呼ばれる)の秘密キーでデジタル署名されます。この項の残りの部分では、CAという用語は、証明書に署名するエンティティの意味で使用されます。
ユーザーは、主体の公開キー証明書に署名したCAの公開キーの信頼できるコピーを持っていない場合、署名しているCAを保証する別の公開キー証明書が必要です。この論理は、証明書の連鎖(または証明書パス)が信頼できるアンカーまたは最も信頼できるCAから検出されるまで、再帰的にターゲットの主体(一般にエンド・エンティティと呼ばれる)に適用されます。通常、もっとも信頼できるCAは、ユーザーが直接信頼するCAに宛てて発行した証明書によって指定されます。一般に証明書パスは順序付けされた証明書のリストで、通常の場合、エンド・エンティティの公開キー証明書と0個以上の付加的な証明書で構成されます。通常、証明書パスには1つ以上のエンコードがあります。これにより、証明書パスは、安全にネットワークを通じて伝送されたり、別のオペレーティング・システム・アーキテクチャへ送信されたりします。
次の図は、もっとも信頼できるCAの公開キー(CA 1)からターゲットの主体(Alice)への証明書パスを示しています。証明書パスは、CA2という名前の中間CAを介して、Aliceの公開キーとの信頼を確立します。
証明書パスは、主体の公開キーの信頼を確立するため、信頼する前に検証する必要があります。検証では、署名を検証したり、各証明書が取り消されていないことをチェックしたりするなど、証明書パスに含まれている証明書に対するさまざまなチェックを行います。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だけが、法的な契約による義務の下で、有効かつ信頼できる証明書を作成するものと見なされています。VeriSign、Thawte、Entrustをはじめ、多くの公開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 Development Kitツール仕様のkeytool
に関する項を参照してください。
コア・クラスとインタフェース
Java Certification Path APIのコア・クラスは、アルゴリズムおよび実装に依存しない方式で証明書パスの機能をサポートするインタフェースおよびクラスで構成されています。
java.security.cert
パッケージに構築され、その機能を拡張します。コア・クラスは、次のように基本、検証、構築およびストレージという4つのクラス・カテゴリに分けることができます。
-
-
CertPath
、CertificateFactory
およびCertPathParameters
-
-
-
CertPathValidator
、CertPathValidatorResult
およびCertPathChecker
-
-
-
CertPathBuilder
およびCertPathBuilderResult
-
-
-
CertStore
、CertStoreParameters
、CertSelector
およびCRLSelector
-
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
メソッドは、証明書パスに含まれる証明書のリストを返します。
このメソッドは、0個以上のpublic abstract List<? extends Certificate> getCertificates()
java.security.cert.Certificate
オブジェクトのList
を返します。返されるList
およびその中に含まれるCertificates
は、CertPath
オブジェクトの内容を保護するため、変更できません。返される証明書の順序付けは、型に依存します。規則により、X.509型のCertPath
オブジェクト内の証明書は、ターゲットとなる証明書から順に並べられ、信頼できるアンカーによって発行された証明書が最後に置かれます。つまり、証明書の発行者は、その次に続く証明書の主体になります。TrustAnchor
を表す証明書を証明書パスに含めることはできません。ただし、検証されていないX.509のCertPath
は、この規則に従っていないことがあります。PKIXCertPathValidator
は、この規則の違反を検出することにより、証明書パスが無効になり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
オブジェクトが生成されると、それはCertPathValidator
のvalidate
メソッドに渡され、検証されます。これらの概念の詳細については、続くセクションで説明します。
CertificateFactoryクラス
CertificateFactory
クラスは、証明書ファクトリの機能を定義するエンジン・クラスです。Certificate
、CRL
およびCertPath
オブジェクトを生成するために使用されます。
CertificateFactory
をCertPathBuilder
と混同しないでください。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
インタフェースと同様に、CertPathValidatorResult
はCloneable
を拡張し、例外をスローしない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
インタフェースを実装するオブジェクトは、CertPathBuilder
のbuild
メソッドによって返されます。
次のコード例では、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 CertStore
はCertStoreException
をスローすることがあります。
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
インタフェースを実装している、LDAPCertStoreParameters
とCollectionCertStoreParameters
という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
またはCRL
のCollection
を返します。また、CertSelector
は、証明書パスのターゲットまたはエンド・エンティティ証明書で、検証の制約を指定するためにも使用されます(例については、PKIXParameters.setTargetCertConstraints
メソッドを参照)。
X509CertSelectorクラス
X509CertSelector
クラスは、X.509証明書を選択するための一連の条件を定義するCertSelector
インタフェースの実装です。
X509Certificate
オブジェクトは、match
メソッドによって選択されるには、指定された条件のすべてを満たす必要があります。この選択条件は、CertPathBuilder
実装がX.509証明書パスを構築する際に、潜在的な証明書を検出するために使用するよう設計されています。
たとえば、X509CertSelector
のsetSubject
メソッドを使用すると、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)
指定された識別名(X500Principal
、RFC 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証明書パスにある証明書の失効ステータスをチェックするのに役立つよう設計されています。
たとえば、X509CRLSelector
のsetDateAndTime
メソッドを使用すると、PKIX CertPathValidator
は、指示された時間のあとに発行された、または指示された時間の前に期限が切れるX509CRL
をフィルタにかけることができます。X509CRLSelector
オブジェクトで、この条件とともにその他の条件を設定することにより、CertPathValidator
は、無関係なCRLを破棄して、証明書が取り消されているかどうかをより簡単にチェックできます。
この項で説明したX.509 CRLフィールドおよび拡張機能の定義については、RFC 5280を参照してください。
X509CRLSelectorオブジェクトの生成
X509CRLSelector
オブジェクトは、次のようにしてデフォルトのコンストラクタを呼び出すことにより生成されます。
public X509CRLSelector()
最初は、条件は何も設定されていません(どのX509CRL
も一致)。
選択条件の設定
呼出し側は、選択条件を使用してX.509 CRLの異なるコンポーネントを照合できます。ここでは、選択条件を設定するほとんどのメソッドについて説明します。残りのメソッドの詳細は、
のAPIドキュメントを参照してください。
X509CRLSelectorクラス
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
メソッドを使って取得できます。これらのメソッドの詳細は、
のAPIドキュメントを参照してください。
X509CRLSelectorクラス
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
として指定されている場合、getCA
、getCAName
、および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
メソッドを使って取得できます。これらのメソッドの詳細は、
のAPIドキュメントを参照してください。
Class PKIXParameters
PKIXCertPathValidatorResultクラス
PKIXCertPathValidatorResult
クラスは、PKIX証明書パス検証アルゴリズムの結果を表します。
このクラスは、CertPathValidatorResult
インタフェースを実装します。 検証アルゴリズムの実行結果である有効なポリシー・ツリーおよび主体の公開キーが保持され、それらを返すためのメソッド(getPolicyTree()
およびgetPublicKey()
)が含まれます。PKIXCertPathValidatorResult
のインスタンスは、PKIXアルゴリズムを実装するCertPathValidator
オブジェクトのvalidate
メソッドによって返されます。
このクラスの詳細は、
のAPIドキュメントを参照してください。
PKIXCertPathValidatorResult
PolicyNodeインタフェースおよびPolicyQualifierInfoクラス
PKIX検証アルゴリズムは、証明書ポリシー処理に関連のあるいくつかの出力を定義します。ほとんどのアプリケーションは、これらの出力を使用する必要はありませんが、PKIX検証を実装しているかまたはアルゴリズムを構築しているプロバイダはすべて、それらの出力をサポートする必要があります。
PolicyNode
インタフェースは、PKIX証明書パス検証が正常に実行されると作成される有効なポリシー・ツリーのノードを表します。アプリケーションは、PKIXCertPathValidatorResult
のgetPolicyTree
メソッドを使って、有効なポリシー・ツリーのルートを取得できます。ポリシー・ツリーの詳細は、RFC 5280を参照してください。
PolicyNode
のgetPolicyQualifiers
メソッドは、PolicyQualifierInfo
オブジェクトのSet
を返します。その各オブジェクトは、このポリシーが適用される適切な証明書のCertificate Policies拡張情報に含まれるポリシー修飾子を表します。
ほとんどのアプリケーションでは、有効なポリシー・ツリーおよびポリシー修飾子を調べる必要はありません。PKIXParameters
でポリシー関連のパラメータを設定することにより、アプリケーションのポリシー処理目標を実現できます。ただし、有効なポリシー・ツリーは、より複雑なアプリケーション、特にポリシー修飾子を処理するアプリケーションに利用できます。
これらのクラスの詳細は、
およびInterface PolicyNode
のAPIドキュメントを参照してください。
PolicyQualifierInfo
例10-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());
}
検証アルゴリズムが成功したら、その検証アルゴリズムで生成されたポリシー・ツリーおよび主体の公開キーを、PKIXCertPathValidatorResult
のgetPolicyTree
および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
を取得します。
このクラスの詳細は、
のAPIドキュメントを参照してください。
PKIXCertPathBuilderResult
例10-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
実装によって提供される失効メカニズムが適さない場合。たとえば、
(JDK 8で導入。PKIXRevocationCheckerクラスを使った証明書の失効ステータスのチェックを参照)を使用して失効メカニズムをより詳細に制御したり、独自の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つのメソッド(check
、getSupportedExtensions
、init
、およびisForwardCheckingSupported
)があり、すべての固定サブクラスはこれらを実装する必要があります。
PKIXCertPathChecker
の実装は、簡単な場合と複雑な場合があります。PKIXCertPathChecker
実装には、ステートレスとステートフルがあります。ステートレスな実装では、check
メソッドの連続する呼出しの間で、状態が維持されません。たとえば、特定のポリシー修飾子を含む各証明書を確認するPKIXCertPathChecker
はステートレスです。それに対して、ステートフルな実装では、check
メソッドの連続する呼出しの間で、状態を維持します。通常、ステートフルな実装のcheck
メソッドは、証明書パス内の以前の証明書の内容に依存します。たとえば、NameConstraints拡張情報を処理するPKIXCertPathChecker
はステートフルです。
また、サービス・プロバイダ実装によって処理される証明書がPKIXCertPathChecker
に提供される(渡される)順序は、実装がステートフルである場合は特に重要です。証明書は、サービス・プロバイダが使用するアルゴリズムによって逆方向または順方向の順序で渡されます。逆方向とは、証明書がもっとも信頼できるCA (存在する場合)からターゲットの主体へと順序付けられていることを意味します。それに対して順方向とは、証明書がターゲットの主体からもっとも信頼できるCAへと順序付けられていることを意味します。PKIXCertPathChecker
実装には、連続した証明書の処理方法を理解できるようにするため、順序を知らせる必要があります。
PKIXCertPathCheckerオブジェクトの初期化
init
メソッドは、チェッカの内部状態を初期化します。
public abstract void init(boolean forward)
すべてのステートフルな実装は、チェッカの内部状態をクリアまたは初期化する必要があります。こうすれば、サービス・プロバイダ実装は、初期化されていない状態のチェッカを呼び出すことができません。また、ステートフルなチェッカは、インスタンスを再度生成しなくても、以降の操作でそれを再利用できます。forward
パラメータは、PKIXCertPathChecker
に渡される証明書の順序を示します。forward
がtrue
である場合、証明書はターゲットから信頼できるアンカーに渡され、false
の場合、信頼できるアンカーからターゲットに渡されます。
順方向のチェック
isForwardCheckingSupported
メソッドは、PKIXCertPathChecker
が順方向のチェックをサポートするかどうかを示すboolean
を返します。
public abstract boolean isForwardCheckingSupported()
すべてのPKIXCertPathChecker
実装は逆方向のチェックをサポートしている必要があります。PKIXCertPathChecker
実装は順方向のチェックをサポートできます。
順方向のチェックをサポートすると、パスが構築時にチェックされるので、順方向に構築するCertPathBuilder
の効率が向上します。ただし、ステートフルなPKIXCertPathChecker
では、順方向チェックのサポートが難しいか、または不可能な場合があります。
サポートされる拡張情報
getSupportedExtensions
メソッドは、PKIXCertPathChecker
実装がサポートする(つまり、認識し、処理できる) X.509拡張情報の不変のOID String
のSet
を返します。
public abstract Set<String> getSupportedExtensions()
拡張情報が処理されない場合、メソッドはnull
を返す必要があります。すべての実装は、check
メソッドが処理するOID String
のSet
を返す必要があります。
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
実装が効率的に戻り、別のパスを試すことができるようにするためです。この場合、実装は、複製されたオブジェクトを復元することにより、以前のパスの検証状態を復元できます。
例10-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 below 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()
メソッドは例外をスローします。
基本のステップは次のとおりです。
- CAルート証明書および検証する証明書パスを取得します。
- 信頼できるアンカーで
PKIXParameters
を作成します。 CertPathValidator
を使用して、証明書パスを検証します。
この例では、getTrustAnchors()
およびgetCertPath()
がCAルート証明書と証明書パスを取得するメソッドです。
この例のgetTrustAnchors()
メソッドは、検証に使用したいCAルート証明書を表すTrustAnchor
のSet
を返す必要があります。これは、ファイルから単一の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
を追加します。この例では、SimpleChecker
はPKIXCertPathChecker
サブクラスです。新しい行を太字で示します。
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);
SimpleChecker
はPKIXCertPathChecker
の基本的なサブクラスです。そのcheck()
メソッドは、検証される証明書パス内のすべての証明書に対して呼び出されます。SimpleChecker
はAlgorithmConstraints
実装を使用して、各証明書の署名アルゴリズムと公開キーを調査します。
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)を使って証明書の失効ステータスをチェックします。
(JDK 8で導入)は、PKIXRevocationChecker
PKIXCertPathChecker
のサブクラスであり、PKIXアルゴリズムを使用して証明書の失効ステータスをチェックします。
PKIXRevocationChecker
のインスタンスは、オンライン証明書ステータス・プロトコル(OCSP)または証明書の失効リスト(CRL)を使って証明書の失効ステータスをチェックします。OCSPは、RFC 2560に記述されている、証明書のステータスを判定するためのネットワーク・プロトコルです。CRLは、失効した証明書を識別するタイム・スタンプ付きのリストです。RFC 5280には、CRLを使って証明書の失効ステータスを判定するためのアルゴリズムが記述されています。
PKIX CertPathValidator
およびCertPathBuilder
の各インスタンスは、デフォルトで有効になるデフォルトの失効実装を提供します。その実装で使用される失効設定をより詳細に制御する必要がある場合は、PKIXRevocationChecker
クラスを使用します。
PKIXRevocationChecker
クラスを使って証明書パスの失効ステータスをチェックするには、これらの一般的なステップを実行します。
-
PKIX
CertPathValidator
またはCertPathBuilder
インスタンスのgetRevocationChecker
メソッドを呼び出して、PKIXRevocationChecker
インスタンスを取得します。 -
PKIXRevocationChecker
クラスに含まれるメソッドを使って、証明書の失効に固有の追加パラメータおよびオプションを設定します。これらのメソッドには、OCSP応答者の場所を特定するURIを設定する
(ただし、通常このURIは証明書に含まれているため、設定する必要はありません)と、失効オプションを設定するsetOCSPResponder(URI)
が含まれています。setOptions(Set<PKIXRevocationChecker.Option>)
は、次のオプションを指定するために使用される列挙型です。PKIXRevocationChecker.Option
ONLY_END_ENTITY
: エンドエンティティ証明書の失効ステータスのみをチェックします。PREFER_CRLS
: デフォルトでは、OCSPが失効ステータスをチェックするための推奨メカニズムであり、CRLは代替メカニズムです。この設定を切り替えるには、このオプションを使用します。SOFT_FAIL
: ネットワーク障害を無視します。
-
PKIXRevocationChecker
のインスタンスを取得したら、
またはaddCertPathChecker
メソッドを使用してsetCertPathCheckers
PKIXParameters
またはPKIXBuilderParameters
オブジェクトにそれを追加します。 -
PKIX
CertPathValidator
またはCertPathBuilder
インスタンスのどちらを使用するかに応じて、これらのステップのいずれかを実行します。 -
検証する証明書パスと、失効チェッカを含む
PKIXParameters
またはPKIXBuilderParameters
オブジェクトを引数として指定して、PKIXCertPathValidator
またはCertPathBuilder
インスタンスのvalidate
メソッドを呼び出します。
次の抜粋は、証明書パスに含まれる証明書の失効ステータスをチェックします。CertPath
オブジェクトpath
は証明書パスです。params
はPKIXParameters
型のオブジェクトです。
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
を使用することがあります。たとえば、LDAPCertStore
実装は、X.509CertificateFactory
を使用して、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.509CertPath
型とPKCS7およびPkiPathエンコードCertPathValidator
: PKIXアルゴリズムCertPathBuilder
: PKIXアルゴリズムCertStore
: CollectionCertStore
型
これらのサービス・プロバイダ・インタフェースの実装については、それぞれ次で詳しく説明します。
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
を構築します。各CertPath
はRFC 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"が指定されていると仮定)。
- 証明書の発行者DNが、指定された
TrustAnchor
のうち1つのDNと一致(例: issuerDN = "ou=D,ou=C,o=B,c=A")。 - 証明書の発行者DNが
TrustAnchor
のうち1つのDNの子孫で、アンカーに近いほうから順に順序付けられている(例: issuerDN = "ou=E,ou=D,ou=C,o=B,c=A")。 - 証明書の発行者DNが
TrustAnchor
のうち1つのDNの祖先で、アンカーに近いほうから順に順序付けられている(例: issuerDN = "ou=C,o=B,c=A")。 - 証明書の発行者DNが
TrustAnchor
のうち1つの同じ名前空間内にあり、アンカーに近いほうから順に順序付けられている(例: issuerDN = "ou=G,ou=C,o=B,c=A")。 - 証明書の発行者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に設定した場合、SunのPKIX実装は、指定されるCertStores
に加えて証明書のCRL配布ポイント拡張機能の情報を使用して、CRLを検索します。ただし、配布ポイントがX.500識別名、またはldap、httpまたはftp型のURIである必要があります。
注意:
ネットワークとファイアウォールの設定によっては、ネットワーキング・プロキシ・サーバーも構成する必要がある場合があります。Authority Information Access (AIA)拡張機能のサポート
Authority Information Access拡張機能のcaIssuers
アクセス・メソッドに対して、サポートが提供されます。これは、デフォルトでは互換性を維持するため無効になっています。システム・プロパティcom.sun.security.enableAIAcaIssuers
の値をtrueに設定すると、これが有効になります。
trueに設定した場合、SunのCertPathBuilder
PKIX実装は、指定されるCertStoreに加えて証明書のAIA拡張機能の情報を使用して、発行するCA証明書を検索します。ただし、それがldap、httpまたはftp型のURIである必要があります。
注意:
ネットワークとファイアウォールの設定によっては、ネットワーキング・プロキシ・サーバーも構成する必要がある場合があります。CRLの取得の最大ネットワーク接続タイムアウト
システム・プロパティcom.sun.security.crl.timeout
によってCRLの取得の最大接続タイムアウトを秒単位で設定します。このプロパティが設定されていないか、負の値の場合は、デフォルト値の15秒に設定されます。値0は、無限タイムアウトを意味します。
CRL取得の最大読取りタイムアウト
システム・プロパティcom.sun.security.crl.readtimeout
によってCRLの取得の最大読取りタイムアウトを秒単位で設定します。読取りタイムアウトにより、接続が確立されたときにCRLダウンロードに時間がかかることを防止できます。このプロパティが設定されていないか、負の値の場合は、デフォルト値の15秒に設定されます。値0は、無限タイムアウトを意味します。
付録C: OCSPサポート
RFC 2560に定義されているOCSP (On-Line Certificate Status Protocol)のクライアント側サポートが提供されています。
プロパティ名 | 説明 |
---|---|
ocsp.enable |
このプロパティの値は、trueまたはfalseになる。trueの場合、OCSPチェックは証明書失効チェックの実行中に有効になる。falseまたは設定されていない場合、OCSPチェックは無効になる。 |
ocsp.responderURL |
このプロパティの値は、OCSP応答者の場所を特定するURLである。次に例を示します デフォルトでは、OCSP応答者の場所は、検証される証明書から暗黙的に決定される。RFC 5280に定義されているAuthority Information Access拡張機能が証明書にない場合、またはオーバーライドが必要な場合に、このプロパティが使用される。 |
ocsp.responderCertSubjectName |
このプロパティの値は、OCSP応答者の証明書の主体名である。次に例を示します デフォルトでは、OCSP応答者の証明書は、検証される証明書の発行者のものである。このプロパティは、デフォルトが適用されない場合に、OCSP応答者の証明書を特定する。この値はRFC 2253で定義された文字列の識別名で、証明書パスの検証中に取得した証明書セットの中から証明書を特定する。サブジェクト名だけでは証明書を一意に特定できない場合は、 |
ocsp.responderCertIssuerName |
このプロパティの値は、OCSP応答者の証明書の発行者名である。次に例を示します デフォルトでは、OCSP応答者の証明書は、検証される証明書の発行者のものである。このプロパティは、デフォルトが適用されない場合に、OCSP応答者の証明書を特定する。この値はRFC 2253で定義された文字列の識別名で、証明書パスの検証中に取得した証明書セットの中から証明書を特定する。このプロパティが設定されている場合、 |
ocsp.responderCertSerialNumber |
このプロパティの値は、OCSP応答者の証明書のシリアル番号である。次に例を示す デフォルトでは、OCSP応答者の証明書は、検証される証明書の発行者のものである。このプロパティは、デフォルトが適用されない場合に、OCSP応答者の証明書を特定する。この値は16進数の文字列(コロンまたはスペースで区切られている)で、証明書パスの検証中に取得した証明書セットの中から証明書を特定する。このプロパティが設定されている場合、 |
これらのプロパティは、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選択条件によって、証明書を別の位置からフェッチします。実装は、次の操作をできるだけ多く実行します。
- Subject non-null, basicConstraints <= -1
主体DNの「userCertificate」属性で証明書を検索します。
- Subject non-null, basicConstraints >= -1
主体DNの「crossCertificatePair」属性の順方向の要素内にあり、かつ主体の「caCertificate」属性内にある証明書を検索します。
- Issuer non-null, basicConstraints >= -1
発行者DNの「crossCertificatePair」属性の逆方向要素内にあり、かつ発行者DNの「caCertificate」属性内にある証明書を検索します。
どの場合も、証明書は検索結果のコレクションに追加する前に、X509CertSelector.match()を使ってチェックされます。
上記に指定した条件のどれも当てはまらない場合、提供された条件を使って証明書をフェッチできなかったことを示す例外がスローされます。1つ以上の条件が適用されたとしても、ディレクトリに証明書がない場合、返されるCollectionは空のままであることに注意してください。
実装は、X509CRLSelector
クラスのsetCertificateChecking、addIssuerName、またはsetIssuerNamesメソッドで指定された発行者DNからCRLをフェッチします。いずれかのメソッドを使って発行者DNを指定しないと、実装により、指定された基準ではCRLをフェッチできなかったことを示す例外がスローされます。それ以外の場合、CRLは次のように検索されます。
-
最初に、実装により発行者名のリストが作成されます。setCertificateCheckingメソッドに証明書が指定されている場合、その証明書の発行者が使用されます。それ以外の場合、addIssuerNameまたはsetIssuerNamesメソッドで指定された発行者名が使用されます。
-
次に、発行者名のリストに対して反復処理が行われます。これは、発行者名ごとに、まず発行者の
authorityRevocationList
属性内を検索し、一致するCRLが見つからなかった場合は、発行者のcertificateRevocationList
属性内を検索します。ただし、setCertificateCheckingメソッドに指定された証明書から発行者名を取得した場合は例外であり、指定された証明書がCA証明書である場合は、発行者のauthorityRevocationList
属性のみをチェックします。 -
すべてのCRLは検索結果のコレクションに追加する前に、X509CRLSelector.match()を使ってチェックされます。
-
選択基準を満たす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
プロパティの値を変更できます。ただし、現在のアルゴリズムまたはキー・サイズを削除することはお薦めできません。