Provider クラス
Security クラス
MessageDigest クラス
Signature クラス
AlgorithmParameterSpec インタフェース
DSAParameterSpec クラス
AlgorithmParameters クラス
AlgorithmParameterGenerator クラス
Key インタフェース
鍵仕様のインタフェースおよびクラス
KeySpec インタフェース
DSAPrivateKeySpec クラス
DSAPublicKeySpec クラス
RSAPrivateKeySpec クラス
RSAPrivateCrtKeySpec クラス
RSAMultiPrimePrivateCrtKeySpec クラス
RSAPublicKeySpec クラス
EncodedKeySpec クラス
PKCS8EncodedKeySpec クラス
X509EncodedKeySpec クラス
KeyFactory クラス
CertificateFactory クラス
KeyPair クラス
KeyPairGenerator クラス
KeyStore クラス
SecureRandom クラス
Cipher クラス
CipherStream クラス
CipherInputStream クラス
CipherOutputStream クラス
KeyGenerator クラス
SecretKeyFactory クラス
SealedObject クラス
KeyAgreement クラス
Mac クラスMessageDigest オブジェクトの計算
鍵仕様および KeyFactory を使った署名の生成と検証
Security API は Java プログラミング言語のコア API で、
java.securityパッケージ (およびそのサブパッケージ) に組み込まれています。この API は、開発者が低レベルと高レベルの両方のセキュリティ機能をプログラムに組み込めるように設計されています。JDK 1.1 で Security API が初めてリリースされた際、「Java 暗号化アーキテクチャ」(JCA) が導入されました。JCA とは、Java プラットフォームに暗号機能を開発し、これにアクセスするためのフレームワークのことです。JDK 1.1 では、JCA にデジタル署名とメッセージダイジェストの API が含められました。
続いてリリースされた Java 2 SDK では、このドキュメントで説明するように、Java 暗号化アーキテクチャが著しく拡張されています。また、X.509 v3 証明書をサポートする証明書管理インフラストラクチャがアップグレードされ、柔軟性と拡張性があり、適合性が高く細かいアクセス制御が可能な新しい Java セキュリティアーキテクチャが導入されています。
Java 暗号化アーキテクチャは、Java 2 SDK Security API の暗号化に関連する部分を組み込んでいます。また、このドキュメントに記載されている一連の規則と仕様も取り入れました。複数の暗号の実装とその相互運用を可能にする「プロバイダ」アーキテクチャも含まれています。
JavaTM 暗号化拡張機能 (JCE) は、暗号化、鍵生成と鍵協定、およびメッセージ認証コード (MAC) アルゴリズム用のフレームワークおよび実装を提供します。暗号化サポートには、対称、非対称、ブロック、およびストリーム暗号が含まれます。このソフトウェアは、セキュリティ保護されたストリームおよびシールされたオブジェクトもサポートします。
JavaTM 2 SDK, Standard Edition (Java 2 SDK) バージョン 1.2.x および 1.3.x では、JCE はオプションパッケージ (拡張機能) でした。Java 2 SDK 1.4 リリース以降では JCE が統合されています。
JCE API には、以下が含まれます。
- 対称バルク暗号化 (DES、RC2、および IDEA など)
- 対称ストリーム暗号化 (RC4 など)
- 非対称暗号化 (RSA など)
- パスワードベース暗号化 (PBE)
- 鍵協定
- メッセージ認証コード (MAC)
Java 2 SDK, v 5.0 リリースには、
SunJCEという名前の標準 JCE プロバイダがあらかじめインストールおよび登録されています。SunJCE は、次の暗号化サービスを提供します。
- Electronic Code Book (ECB)、Cipher Block Chaining (CBC)、Cipher Feedback (CFB)、Output Feedback (OFB)、および Propagating Cipher Block Chaining (PCBC) モードの DES (FIPS PUB 46-1)、トリプル DES、および Blowfish 暗号化アルゴリズムの実装 (注: このドキュメントでは、「トリプル DES」と「DES-EDE」を同じものとする)
- DES、トリプル DES、Blowfish、HMAC-MD5、および HMAC-SHA1 アルゴリズムに適した鍵を生成する鍵ジェネレータ
- PKCS #5 で定義された DES-CBC パスワードベース暗号化 (PBE) アルゴリズムを使用する MD5 の実装
- 不透明な DES、トリプル DES、PBE 鍵オブジェクトと、背後の鍵データの透明な表現との双方向変換を提供する「秘密鍵ファクトリ」
- 複数のパーティ間での Diffie-Hellman 鍵協定アルゴリズムの実装
- Diffie-Hellman アルゴリズムに適した公開値および非公開値のペアの生成に必要な Diffie-Hellman 鍵ペアジェネレータ
- Diffie-Hellman アルゴリズムのパラメータジェネレータ
- 不透明な Diffie-Hellman 鍵オブジェクトと背後の鍵データの透明な表現との間の双方向変換を提供する Diffie-Hellman「鍵ファクトリ」
- Diffie-Hellman、DES、トリプル DES、Blowfish、および PBE パラメータ用のアルゴリズムパラメータマネージャ
- RFC 2104 に定義されている、HMAC-MD5 および HMAC-SHA1 キーハッシュアルゴリズムの実装
- PKCS #5 に記載されているパディング方式の実装
- JCEKS という独自のキーストア型のためのキーストアの実装
用語に関する注記
Java 2 SDK, v 5.0 の JCE には、次の 2 つのソフトウェアコンポーネントが含まれます。
このドキュメントでは、「JCE」という語は、Java 2 SDK, v 5.0 の JCE フレームワークを指して使われています。Java 2 SDK, v 5.0 とともに提供される JCE プロバイダに言及する場合、常に「SunJCE」プロバイダのことを明示的に指しています。
- プロバイダが実装を提供可能な暗号化サービスを定義および提供するフレームワーク。このフレームワークには、
javax.cryptoパッケージ内のすべてが含まれる- 「SunJCE」という名前のプロバイダ
注: この JCA 仕様の最新版については、次のサイトを参照してください。http://java.sun.com/j2se/1.5.0/docs/guide/security/CryptoSpec.html
Java 暗号化アーキテクチャ (JCA) は、以下の方針に基づいて設計されました。
- 実装の独立性と相互操作性
- アルゴリズムの独立性と拡張性
実装の独立性とアルゴリズムの独立性は相補関係にあります。そのため、デジタル署名やメッセージダイジェストなどの暗号化サービスを、実装の詳細やこれらの概念の基になるアルゴリズムを意識しないで使用できます。完全なアルゴリズムの独立性が不可能なときは、JCA は標準化された、アルゴリズム依存の API を提供します。実装の独立性が望ましくない場合、JCA では、開発者が特定の実装を指定できます。
アルゴリズムの独立性は、暗号化「エンジン」(サービス) の型を定義し、これらの暗号化エンジンの機能を提供するクラスを定義することにより実現しています。これらのクラスは「エンジンクラス」と呼ばれ、
MessageDigestクラス、Signatureクラス、KeyFactoryクラス、およびKeyPairGeneratorクラスがこれに含まれます。実装の独立性は、「プロバイダ」ベースのアーキテクチャを使って実現されます。暗号化サービスプロバイダ (このドキュメントでは「プロバイダ」とも呼ばれる) とは、デジタル署名アルゴリズム、メッセージダイジェスト、および鍵の変換サービスなどの 1 つ以上の暗号化を実行するパッケージやパッケージセットを意味します。プログラムは単に、特定のサービス (たとえば DSA 署名アルゴリズム) を実行する特定型のオブジェクト (たとえば
Signatureオブジェクト) を要求するだけで、インストールされているプロバイダの 1 つから実装を獲得できます。必要に応じて、プログラムは特定プロバイダから実装を要求することもできます。たとえば、より高速で安全性の高いバージョンが利用できるときは、プロバイダをアプリケーションに対して透過的に更新することができます。実装の相互操作性とは、さまざまな実装が互いに機能でき、互いの鍵を使ったり、互いの署名を検証できることを意味します。つまり、1 つのプロバイダが生成した同じアルゴリズムや鍵を別のプロバイダが使ったり、あるプロバイダが生成した署名を別のプロバイダが検証するということです。
アルゴリズムの拡張性とは、サポートされるエンジンクラスの 1 つに当てはまる新規アルゴリズムを容易に追加できることを意味します。
暗号化サービスプロバイダ
Java 暗号化アーキテクチャに、「暗号化サービスプロバイダ」(このドキュメントでは「プロバイダ」とも呼ばれる) の概念が導入されました。これは、Security API の暗号化に関するサブセットの固定実装を提供するパッケージ (またはパッケージセット) です。
たとえば、JDK 1.1 では、プロバイダには、1 つ以上のデジタル署名アルゴリズム、メッセージダイジェストアルゴリズム、および鍵生成アルゴリズムの実装などを含めることができました。Java 2 SDK では鍵ファクトリ、キーストアの作成および管理、アルゴリズムパラメータの管理、アルゴリズムパラメータの生成、および証明書ファクトリの 5 種類のサービスが追加されています。また、Java 2 SDK では、プロバイダが乱数の生成 (RNG) アルゴリズムを提供できます。これまで、JDK では、特定のアルゴリズムはハードコードされており、RNG もプロバイダベースではありませんでした。
すでに説明したように、プログラムは単に、特定サービス (たとえば DSA 署名アルゴリズム) 用の特定型のオブジェクト (たとえば
Signatureオブジェクト) を要求するだけで、インストールされているプロバイダの 1 つから実装を獲得できます。あるいは、特定プロバイダのオブジェクトを要求することもできます(各プロバイダは、それぞれの参照名を持つ)。Sun が提供する Java Runtime Environment には、
SUNという名前のデフォルトのプロバイダが標準で搭載されています。ほかの Java Runtime Environment には、SUNプロバイダが含まれない場合があります。SUNプロバイダパッケージには、以下のものが含まれています。
- NIST FIPS 186 に記述されたデジタル署名アルゴリズム (DSA) の実装
- MD5 (RFC 1321) および SHA-1 (NIST FIPS 180-1) メッセージダイジェストアルゴリズムの実装
- DSA アルゴリズムに適した公開鍵および非公開鍵のペアの生成に必要な DSA 鍵のペアのジェネレータ
- DSA アルゴリズムパラメータジェネレータ
- DSA アルゴリズムパラメータマネージャ
- (不透明な) DSA 非公開鍵および公開鍵オブジェクトとそれらの基本となる鍵データとの双方向変換を可能にする DSA 「鍵ファクトリ」
- IEEE P1363 標準 (Appendix G.7) の推奨に準拠した専用の「SHA1PRNG」擬似乱数生成アルゴリズムの実装
- 「Internet X.509 Public Key Infrastructure Certificate and CRL Profile」(このドキュメントの執筆時点で、Internet Engineering Task Force から草稿として入手可能) に規定されている PKIX 用の証明書パスビルダおよびバリデータ
- PKIX LDAP V2 スキーマ (RFC 2587) を使用して証明書と CRL を Collection ディレクトリおよび LDAP ディレクトリから取得するための証明書ストアの実装
- X.509 証明書の取り消しリスト (CRL) のための証明書ファクトリ
JKSという独自のキーストア型のためのキーストアの実装SDK では 1 つ以上のプロバイダパッケージがインストールされます。新規プロバイダは静的または動的に追加できます (Provider クラスと Security クラスを参照)。Java 暗号化アーキテクチャには、インストールされているプロバイダおよびそれらがサポートするサービスについて、ユーザが問い合わせることができる API セットがあります。
クライアントは異なるプロバイダを用いて実行環境を構成し、各プロバイダの「優先順位」を指定できます。優先順位とは、特定プロバイダの指定がない場合に、要求されたサービスに関して検索されるプロバイダの順位です。
鍵管理
「キーストア」と呼ばれるデータベースは、鍵および証明書のリポジトリを管理するために使用できます。キーストアは、証明書または署名の目的でキーストアが必要なアプリケーションで利用できます。
アプリケーションは、
KeyStoreクラスの実装を経由してキーストアにアクセスできます。キーストアクラスの実装は、java.securityパッケージ内にあります。デフォルトのキーストアの実装は、米国 Sun Microsystems, Inc によって提供されます。これは、JKS という名前の独自のキーストアタイプ (形式) を使用するもので、キーストアをファイルとして実装しています。アプリケーションでは、
KeyStoreクラスで提供されるgetInstanceファクトリメソッドを使って、異なるプロバイダから提供される数種類のキーストア実装から選択できます。詳細は、「鍵管理」の項を参照してください。
この項では、API に導入された重要な概念について説明します。
エンジンクラスとアルゴリズム
「エンジンクラス」は、具体的な実装のない抽象的な方法で暗号化サービスを定義します。
暗号化サービスは、常に特定のアルゴリズムまたは型に関連付けられています。このサービスによって、暗号化の操作 (デジタル署名またはメッセージダイジェスト用など) の提供、暗号化の操作に必要な暗号化データ (鍵またはパラメータ) の生成や提供、あるいは暗号化の操作で使う暗号化鍵を安全にカプセル化するデータオブジェクト (キーストアまたは証明書) の生成が行われます。たとえば、
SignatureクラスおよびKeyFactoryクラスは、エンジンクラスです。Signatureクラスは、デジタル署名アルゴリズムの機能へのアクセスを提供します。DSAKeyFactoryは、(コード化形式または透明な仕様から) DSA 非公開鍵または公開鍵を、それぞれ DSASignatureオブジェクトのinitSignまたはinitVerifyメソッドから利用可能な形式で提供します。Java 暗号化アーキテクチャには、エンジンクラスなどの、暗号化に関連する Java 2 SDK Security パッケージが含まれています。API のユーザは、エンジンクラスを要求および使用して対応する処理を実行します。Java 2 SDK では、次のエンジンクラスが定義されています。
Java 2 SDK のリリース 1.4 では、次の新しいエンジンが追加されました。
MessageDigest: 指定データのメッセージダイジェスト (ハッシュ) の計算に使用する
Signature: データの署名およびデジタル署名の検証に使用する
KeyPairGenerator: 指定のアルゴリズムに適合した、公開鍵、非公開鍵ペアの生成に使用する
KeyFactory:Key型の不透明な暗号化鍵を「鍵仕様」(背後キーデータの透明な表現) に変換したり、その逆の変換を行うために使用する
CertificateFactory: 公開鍵の証明書および証明書の取り消しリスト (CRL) の作成に使用する
KeyStore: 「キーストア」の作成および管理に使用する。キーストアは、鍵のデータベースである。キーストア内の非公開鍵には、鍵に関連した証明連鎖がある。証明連鎖は、対応する公開鍵を認証する。また、キーストアには、信頼できるエンティティからの証明書も格納されている
AlgorithmParameters: パラメータの符号化および復号化など、特定のアルゴリズムのパラメータ管理に使用する
AlgorithmParameterGenerator: 特定のアルゴリズムに適したパラメータセットの生成に使用する
SecureRandom: 乱数または擬似乱数の生成に使用する
CertPathBuilder: 証明書連鎖 (「証明書パス」とも呼ばれる) の構築に使用する
CertPathValidator: 証明書連鎖の検証に使用する
CertStore: リポジトリから証明書とCRLを取得するために使用するエンジンクラスは、(特定の暗号化アルゴリズムに依存しない) 特定の型の暗号化サービス機能へのインタフェースを提供します。これにより、Application Programming Interface (API) メソッドが定義され、API が提供する特定の種類の暗号化サービスにアプリケーションがアクセスできるようになります。実際の実装 (1 つ以上のプロバイダから) は特定アルゴリズムのためのものです。たとえば
注: 「ジェネレータ (generator)」は、最新の内容でオブジェクトを作成しますが、「ファクトリ (factory)」は既存の構成要素 (符号化法など) からオブジェクトを作成します。
Signatureエンジンクラスは、デジタル署名アルゴリズムの機能へのアクセスを提供します。SignatureSpiサブクラスに実際に提供される実装は、DSA を使う SHA-1、RSA を使う SHA-1、または RSA を使う MD5 などの特定の種類の署名アルゴリズムとなります。エンジンクラスが提供するアプリケーションインタフェースは、Service Provider Interface (SPI) として実装されます。つまり、各エンジンクラスに対応する抽象 SPI クラスが存在し、この抽象 SPI クラスによって暗号化サービスプロバイダが実装しなければならない SPI メソッドが定義されます。
エンジンクラスのインスタンスである API オブジェクトは、対応する SPI クラスのインスタンス SPI オブジェクトを private フィールドとしてカプセル化します。API オブジェクトのすべての API メソッドは、final として宣言し、それらを実装することによって、カプセル化される SPI オブジェクトの対応する SPI メソッドが呼び出されます。エンジンクラス (およびそれに対応する SPI クラス) のインスタンスは、エンジンクラスの
getInstanceファクトリメソッドへの呼び出しによって作成されます。SPI クラスの名前は、対応するエンジンクラス名のあとに
Spiを追加した名前になります。たとえば、Signatureエンジンクラスに対応する SPI クラスは、SignatureSpiクラスです。各 SPI クラスは、抽象クラスです。指定したアルゴリズムに対する特定の型のサービスの実装を提供するには、プロバイダは、対応する SPI クラスをサブクラス化して、すべての抽象メソッドの実装を提供する必要があります。
エンジンクラスの別の例に
MessageDigestクラスがあります。このクラスは、メッセージダイジェストアルゴリズムへのアクセスを提供します。MessageDigestSpiサブクラスでのこのクラスの実装は、SHA-1、MD5、または MD2 などの各種メッセージダイジェストアルゴリズムにできます。さらに別の例として、
KeyFactoryエンジンクラスは、不透明な鍵から透明な鍵仕様への変換、またはその逆の変換をサポートします。「鍵仕様のインタフェースおよびクラス」を参照してください。KeyFactorySpiサブクラスは、DSA 公開鍵や DSA 非公開鍵などの特定の種類の鍵の実際の実装を提供します。実装とプロバイダ
各種暗号化サービスの実装は、JCA 暗号化サービスプロバイダが提供します。暗号化サービスプロバイダとは、1 つまたは複数の暗号化サービスの実装を提供する基本パッケージです。「エンジンクラスとアルゴリズム」には、Java 2 SDK のデフォルトのプロバイダである SUN が提供する実装の一覧が記載されています。
その他のプロバイダは、上記のサービスまたはその他のサービス (RSA ベースの署名アルゴリズムや MD2 メッセージダイジェストアルゴリズムなど) について、独自の実装を定義できます。
実装のインスタンスを獲得するためのファクトリメソッド
API の各エンジンクラスについては、エンジンクラス特有の「ファクトリメソッド」を呼び出すことによって特定の実装が要求され、インスタンスが生成されます。ファクトリメソッドは、クラスのインスタンスを返す static メソッドです。
たとえば、該当の
Signatureオブジェクト獲得機構は次のとおりです。ユーザはSignatureクラスのgetInstanceメソッドを呼び出して、オブジェクトを要求します。署名アルゴリズム名 (SHA1withDSA など) を指定し、オプションでプロバイダまたはProviderクラスの名前も指定します。getInstanceメソッドが、指定のアルゴリズムおよびプロバイダのパラメータを満たす実装を検索します。プロバイダの指定がない場合、getInstanceは優先順位に従って登録プロバイダを検索し、指定のアルゴリズムを満たす実装を見つけ出します。プロバイダの登録の詳細は、Providerクラスを参照してください。暗号化の概要
このセクションでは、API により実装される概念、および API 仕様で使用される技術用語の正確な意味に関する高度な説明を提供します。
暗号化および暗号解読
暗号化とは、データ (「クリアテキスト」と呼ばれる) および短い文字列 (「キー」) を受け取って、鍵を知らないサードパーティにとって無意味なデータ (「暗号テキスト」) を生成する処理です。暗号解読とはその逆で、暗号テキストおよび短い鍵文字列を受け取り、クリアテキストを生成する処理です。
パスワードベース暗号化
パスワードベース暗号化 (PBE) では、パスワードから暗号化鍵を導き出します。パスワードから暗号化鍵を取得しようとする攻撃者のタスクを非常に時間のかかるものにするため、大半の PBE 実装では、キーの作成時に乱数への混入 (salt と呼ばれる) が行われます。
暗号
暗号化および暗号解読は、暗号を使って行われます。暗号とは、暗号化方式に従って暗号化および暗号解読を実行可能なオブジェクトのことです。
鍵協定
鍵協定とは、複数のパーティが秘密情報を交換しなくても同じ暗号化鍵を確立可能なプロトコルを指します。
メッセージ認証コード
メッセージ認証コード (MAC) は、信頼できない媒体に送信または格納された情報の完全性を、秘密鍵に基づいてチェックする方法を提供します。一般に、メッセージ認証コードは、秘密鍵を共有する 2 つのパーティ間で送信される情報の有効性を検証する場合に使用されます。
暗号化ハッシュ機能に基づくMAC 機構は、HMAC と呼ばれます。HMAC は、秘密共有鍵と組み合わせて、MD5 や SHA-1 などの任意の暗号化ハッシュ機能で使用できます。HMAC については、RFC 2104 で規定されています。
v1.4 と v5.0 での JCE の相違点を次に示します。
- PKCS #11 の追加機能のサポート
- Solaris 暗号化フレームワークの統合
- ECC アルゴリズムのサポート
- JCA/JCE への
ByteBufferAPI サポートの追加RC2ParameterSpecのサポート- XML 暗号化 RSA-OAEP アルゴリズムの完全なサポート
javax.crypto.EncryptedPrivateKeyInfoからのPKCS8EncodedKeySpecの取得の簡略化- 「PBEWithSHA1AndDESede」と「PBEWithSHA1AndRC2_40」暗号のサポート
- JCE Block Encryption 暗号での XML Encryption Padding アルゴリズムのサポート
- 鍵の最大許容長の動的判定
- SunJCE プロバイダへの RSA 暗号化のサポート
- SunJCE プロバイダへの RC2 および ARCFOUR 暗号のサポート
- HmacSHA256、HmacSHA384、および HmacSHA512 のサポート
PKCS #11 ベースの暗号プロバイダのサポート
5.0 では、ネイティブの PKCS#11 API に対する汎用ゲートウェイとして動作する JCA/JCE プロバイダ、SunPKCS11が実装されました。PKCS #11 は暗号アクセラレータのデファクトスタンダードで、暗号化スマートカードへのアクセスに広く使用されています。管理者およびユーザは、このプロバイダを設定して、任意の PKCS#1 v2.x 互換トークンと通信できます。設定ファイル形式の例を示します。
Solaris 暗号化フレームワークの統合
デフォルトの Java セキュリティプロバイダ設定が 5.0 で変更され、Solaris 10 では Solaris 暗号化フレームワークを使用する
SunPKCS11プロバイダのインスタンスが含まれるようになりました。これは最高の優先度をもつプロバイダで、既存のアプリケーションすべてが Solaris 10 でパフォーマンス向上のメリットを享受できます。Solaris 8 および Solaris 9 での動作に変更はありません。この変更のため、すべての Solaris 10 システムでは、多くの暗号化演算が以前の何倍もの速度で実行されるようになります。暗号によるハードウェア高速化を搭載したシステムでは、100 倍のパフォーマンス向上を見込めます。
ECC アルゴリズムのサポート
5.0 より前では、JCA/JCE フレームワークでは、ECC 関連の暗号化アルゴリズムのクラスはサポートされていませんでした。ECC を利用するユーザは、ECC を実装したサードパーティのライブラリに頼らなければなりませんでした。しかし、このようなライブラリは既存の JCA/JCE フレームワークとはうまく統合されませんでした。5.0 以降は、ECC をサポートするプロバイダ用の ECC クラスが完全にサポートされるようになりました。
次のインタフェースが追加されました。
- java.security.spec.ECField
- java.security.interfaces.ECKey
- java.security.interfaces.ECPublicKey
- java.security.interfaces.ECPrivateKey
次のクラスが追加されました。
ByteBuffer API サポートの追加
ByteBuffer 引数をとるメソッドが、バルクデータの処理に使用する JCE API および SPI クラスに追加されました。ByteBuffer を byte[] より効率的に処理できる場合、プロバイダは engine* メソッドをオーバーライドできます。次の JCE メソッドが ByteBuffer のサポートのために追加されました。
javax.crypto.Mac.update(ByteBuffer input)次の JCA メソッドが ByteBuffer のサポートのために追加されました。
javax.crypto.MacSpi.engineUpdate(ByteBuffer input)
javax.crypto.Cipher.update(ByteBuffer input, ByteBuffer output)
javax.crypto.Cipher.doFinal(ByteBuffer input, ByteBuffer output)
javax.crypto.CipherSpi.engineUpdate(ByteBuffer input, ByteBuffer output)
javax.crypto.CipherSpi.engineDoFinal(ByteBuffer input, ByteBuffer output)java.security.MessageDigest.update(ByteBuffer input)
java.security.Signature.update(ByteBuffer data)
java.security.SignatureSpi.engineUpdate(ByteBuffer data)
java.security.MessageDigestSpi.engineUpdate(ByteBuffer input)RC2ParameterSpec のサポート
5.0 では RC2 アルゴリズム実装が拡張され、入力された鍵の長さとは異なる有効な鍵サイズをサポートします。XML 暗号化 RSA-OAEP アルゴリズムの完全サポート
5.0 より前のJCE では、PKCS#1 v2.1 および W3C Recommendation for XML Encryption の RSA-OAEP 鍵転送アルゴリズムに定義されているように、OAEP および PSS パディングで使用されるデフォルト以外の値を指定するパラメータクラスが定義されていませんでした。したがって、OAEP および PSS パディングに使用されたデフォルト以外の値をアプリケーションで指定する一般的な方法はありませんでした。
5.0 では、新しいパラメータクラスが追加され、OAEP パディングが完全にサポートされます。また、PSS パラメータクラスが拡張されて、API が RSA PSS シグニチャー実装を完全にサポートします。さらに、SunJCE プロバイダが拡張され、OAEPPadding が使用された場合に、
OAEPParameterSpecを受け入れるようになりました。次のクラスが追加されました。
次のメソッドおよびフィールドが、
java.security.spec.PSSParameterSpecに追加されました。public static final PSSParameterSpec DEFAULT
public PSSParameterSpec(String mdName, String mgfName,
AlgorithmParameterSpec mgfSpec,
int saltLen, int trailerField)
public String getDigestAlgorithm()
public String getMGFAlgorithm()
public AlgorithmParameterSpec getMGFParameters()
public int getTrailerField()
javax.crypto.EncryptedPrivateKeyInfo からの PKCS8EncodedKeySpec の取得の簡略化5.0 では、javax.crypto.EncryptedPrivateKeyInfoはただ 1 つのメソッドgetKeySpec(Cipher)を持ち、暗号化されたデータからPKCS8EncodedKeySpecを取得します。この制限のため、ユーザは暗号解読鍵およびパラメータで初期化される暗号を指定する必要があります。ユーザが暗号解読鍵のみを持つ場合、まずパラメータをこのEncryptedPrivateKeyInfoオブジェクトから取得し、適合するCipher実装を確保し、初期化し、そしてgetKeySpec(Cipher)メソッドを呼び出さなければなりません。
EncyptedPrivateKeyInfoの使用をより簡単にし、API にjavax.crypto.SealedObjectと一貫性を持たせるため、次のメソッドが javax.crypto.EncryptedPrivateKeyInfo に追加されました。getKeySpec(Key decryptKey)
getKeySpec(Key decryptKey, String provider)
1.4.2 では、J2SE にバンドルされた暗号化管轄ポリシーファイルによって、暗号/暗号解読に使用する鍵の最大長が制限されます。また、ある種の暗号アルゴリズムのパラメータ値も制限されます。制限のない暗号化管轄ファイルを使用したいユーザは、ファイルを個別にダウンロードする必要があります。また、Cipher インスタンスが、暗号化管轄ファイルで許容された最大値を超える鍵 (またはある種の暗号アルゴリズムのパラメータ) で初期化されると、例外がスローされます。
5.0 では、
Cipherクラスが更新され、管轄ポリシーファイルで設定された鍵の最大長およびパラメータを定義するようになったため、デフォルトの (強度の制限された) 管轄ポリシーファイルがインストールされている場合、アプリケーションはより短かい鍵を使用できます。次のメソッドが javax.crypto.Cipher に追加されました。
public static final int getMaxAllowedKeyLength(String transformation)
throws NoSuchAlgorithmException
public static final AlgorithmParameterSpec
getMaxAllowedParameterSpec(String transformation)
throws NoSuchAlgorithmException;
HmacSHA-256、HmacSHA-384、および HmacSHA-512 アルゴリズムのサポートが 5.0 で追加されました。
一般にアクセスできる RSA 暗号化実装が、SunJCE プロバイダに追加されました。
SunJCE プロバイダに、RC2 (RFC 2268) および ARCFOUR (RC4TM 互換アルゴリズム) 暗号が実装されました。
SunJCE プロバイダに、PBEWithSHA1AndDESede と PBEWithSHA1AndRC2_40 暗号のサポートが追加されました。
W3C XML 暗号で、新しいパディングアルゴリズム、ブロック暗号に対する「ISO10126Padding」が定義されます。詳細については、「5.2 Block Encryption Algorithms」を参照してください。Sun のプロバイダを XML 暗号実装および JSR 106 プロバイダで使用できるようにするため、5.0 ではこのパディングに対するサポートが追加されました。
この項では、Java 暗号化アーキテクチャで提供するコアクラスとインタフェースについて説明します。
エンジン クラス
ProviderクラスとSecurityクラス
MessageDigest、Signature、KeyPairGenerator、KeyFactory、AlgorithmParameters、AlgorithmParameterGenerator、CertificateFactory、KeyStore、SecureRandom、CertPathBuilder、CertPathValidator、およびCertStore
Keyインタフェースおよびクラス
「アルゴリズムパラメータの仕様のインタフェースおよびクラス」および「鍵仕様のインタフェースおよびクラス」 この項では、各クラスおよびインタフェースのメインメソッドの署名を示します。該当する例の項には、クラス (
MessageDigest、Signature、KeyPairGenerator、SecureRandom、KeyFactory、および鍵仕様クラス) の例があります。 Security API パッケージの完全なリファレンスドキュメントを以下に示します。
java.security パッケージの概要java.security.spec パッケージの概要java.security.interfaces パッケージの概要java.security.cert パッケージの概要
Provider クラス「暗号化サービスプロバイダ」(このドキュメントでは「プロバイダ」とも呼ばれる) とは、Java 2 SDK Security API の暗号化機能のサブセットの固定実装を提供するパッケージまたはパッケージセットです。
Providerクラスは、このようなパッケージやパッケージセットへのインタフェースです。プロバイダ名、バージョン番号、その他の情報にアクセスするためのメソッドを備えています。Providerクラスを使用すると、暗号化サービスの実装を登録するだけでなく、その他のセキュリティサービスの実装を登録することもできます。その他のセキュリティサービスは、Java 2 SDK Security API またはその拡張機能の 1 つの一部として定義されている場合があります。暗号化サービスの実装を提供するには、エンティティ (たとえば開発グループ) は実装コードを作成し、
Providerクラスのサブクラスを生成します。Providerサブクラスのコンストラクタは、プロバイダが実装したサービスを検索するために Java 2 SDK Security API が使用する各種プロパティの値を設定します。つまり、サブクラスは、サービスを実装するクラス名を指定します。プロバイダパッケージが実装できるサービスには、さまざまな種類があります。詳細については、「エンジンクラスとアルゴリズム」を参照してください。
実装が違うと、特徴も違ってくる場合があります。ソフトウェアベースのものもあれば、ハードウェアベースのものもあります。プラットフォーム独立のものもあれば、プラットフォーム固有のものもあります。また、レビューや評価用に使えるプロバイダコードもあれば、使えないものもあります。Java 暗号化アーキテクチャ (JCA) では、エンドユーザと開発者の双方が独自のニーズを決定できます。
この項では、エンドユーザのための暗号実装のインストール方法とニーズへの合わせ方、および開発者のための必要な実装の要求方法を説明します。
注: プロバイダの実装の詳細は、「Java 暗号化アーキテクチャ用プロバイダの実装方法」を参照してください。
プロバイダ実装の要求および獲得方法
この API の各エンジンクラスについては、特定の実装が要求され、そのエンジンクラスのgetInstanceメソッドを呼び出してインスタンスが生成されます。このときに、希望するアルゴリズムの名前と、実装したいプロバイダ (またはProviderクラス) の名前 (オプション) を指定します。プロバイダを指定しない場合、
getInstanceは、指定されたアルゴリズムに関連する、要求された暗号化サービスの実装に対応する登録プロバイダを検索します。どの Java 仮想マシン (JVM) でも、プロバイダは指定の「優先順位」でインストールされます。優先順位とは、特定プロバイダの指定がない場合に、プロバイダリストが検索される順位です。たとえば、JVM に、PROVIDER_1とPROVIDER_2という 2 つのプロバイダがインストールされ、次のようになっていると仮定します。ここで、3 つのシナリオについて見てみます。
PROVIDER_1は SHA1withDSA、SHA-1、MD5、DES、DES3 を実装
PROVIDER_1の優先順位が 1 (最高の優先順位)
PROVIDER_2は SHA1withDSA、MD5withRSA、MD2withRSA、MD2、MD5、RC4、RC5、DES、RSA を実装PROVIDER_2の優先順位は 2
- MD5 実装を検索するとする。どちらのプロバイダもこの実装を供給する。
PROVIDER_1が最高の優先順位を持ち最初に検索されるので、PROVIDER_1実装が返される- MD5withRSA 署名アルゴリズムを検索する場合、まず最初に
PROVIDER_1が検索される。実装が見つからないので次にPROVIDER_2が検索される。実装が見つかるので、このプロバイダが返される- SHA1withRSA 署名アルゴリズムを検索する場合を想定する。これを実装するプロバイダはインストールされていないので、
NoSuchAlgorithmExceptionがスローされるプロバイダ引数を持つ
getInstanceメソッドは、必要なアルゴリズムを提供するプロバイダを指定したい開発者のためのものです。たとえば、連邦証明書を受け取ったプロバイダ実装を連邦局が使いたいとします。PROVIDER_1の SHA1withDSA 実装はこの証明書を受け取っていないのに対し、PROVIDER_2の DSA 実装がこれを受け取っていると仮定します。連邦局のプログラムは以下の呼び出しを実行します。
PROVIDER_2が認証された実装を持つため、これを指定します。Signature dsa = Signature.getInstance("SHA1withDSA", "PROVIDER_2");この場合、
PROVIDER_2がインストールされていないと、インストールされている別のプロバイダが要求アルゴリズムを実装している場合であっても、NoSuchProviderExceptionがスローされます。プログラムは、(
SecurityクラスのgetProvidersメソッドを使って) インストールされているプロバイダの一覧を獲得し、一覧から選択することもできます。プロバイダのインストール
プロバイダのインストールは 2 つの部分に分かれます。つまり、プロバイダパッケージクラスのインストールとプロバイダの構成です。
プロバイダクラスのインストール
プロバイダクラスのインストールには、次の 2 つの方法があります。
- クラスが格納されている zip または JAR ファイルを、classpath の任意の場所に置く
- プロバイダ JAR ファイルを、「インストールされた」または「バンドルされた」拡張機能として指定する。拡張機能の配置方法の詳細については、「拡張機能の配置」を参照
プロバイダの構成
次の手順では、認可プロバイダのリストにこのプロバイダを追加します。この手順は、SDK の
lib/securityディレクトリにあるjava.securityファイルを編集することによって静的に行うことができます。つまり、SDK がj2sdk1.2というディレクトリにインストールされている場合、ファイルの位置はj2sdk1.2/lib/security/java.securityになります。java.securityで設定できるプロパティの例を次に示します。security.provider.n=masterClassNameこれはプロバイダを宣言し、その優先順位 n を指定します。優先順位とは、特定プロバイダの指定がない場合に、要求されたサービスに関して検索されるプロバイダの順位です。順位は 1 から始まり、1 が最優先で次に 2、3 ... と続きます。
masterClassNameには、プロバイダのマスタークラスを指定する必要があります。プロバイダのドキュメントでそのマスタークラスを指定します。このクラスは、常にProviderクラスのサブクラスです。サブクラスコンストラクタは、プロバイダが実装したアルゴリズムやその他の機能を検索するために Java 暗号化 API に必要な各種プロパティの値を設定します。マスタークラスが
COM.acme.provider.Acmeで、優先順位が第 3 位のプロバイダとしてAcmeを構成したいとします。このためには、次の行をjava.securityファイルに追加します。プロバイダは、動的に登録することもできます。このためには、security.provider.3=COM.acme.provider.AcmeSecurityクラスのaddProviderまたはinsertProviderAtのどちらかのメソッドを呼び出します。この登録は恒久的ではなく、「信頼できる」プログラムでしか実行できません。Security クラスを参照してください。
Providerクラスのメソッド各
Providerクラスインタフェースは、名前 (現時点では大文字と小文字を区別する)、バージョン番号、およびプロバイダとそのサービスの文字列記述を持ちます。以下のメソッドを呼び出して、これらの情報についてProviderのインスタンスを照会できます。public String getName() public double getVersion() public String getInfo()
Security クラス
Securityクラスは、インストールされているプロバイダおよびセキュリティに関するプロパティを管理します。このクラスに含まれるのは、インスタンスが生成されない static メソッドだけです。 プロバイダの追加または削除、およびSecurityプロパティの設定用メソッドは、信頼できるプログラムによってしか実行できません。現時点での「信頼できるプログラム」は、以下のどれかです。あるコードが、実行しようとしているアクション (プロバイダの追加など) を行うことができるような、信頼できるコードであると判断するには、そのアクションを行う権限がそのアプレットに与えられている必要があります。
- セキュリティマネージャの下で動作していないローカルアプリケーション
- 指定されたメソッドを実行する権限のあるアプレットまたはアプリケーション (以下を参照)
たとえば、Policy のリファレンス実装では、SDK インストールのポリシー構成ファイルには、指定されたコードソースのコードにより許可された権限 (システムリソースへのアクセスの種類) を指定します。詳細は、以降の説明および「デフォルトの Policy の実装とポリシーファイルの構文」と「Java セキュリティアーキテクチャ」を参照してください。
実行されるコードは、常に、特定の「コードソース」から来ると考えられます。コードソースには、そのアプレットの元の場所 (URL) だけでなく、コードの署名に使われた非公開鍵に対応する公開鍵への参照も含まれています。コードソース内の公開鍵は、ユーザのキーストアの別名 (記号名) で参照します。
ポリシー構成ファイル内では、コードソースは、コードベース (URL)、および (
signedByで始まる) 別名の 2 つのコンポーネントで表されます。別名は、コードの署名の検証に使う必要のある公開鍵を含んだキーストアのエントリを識別します。このようなファイル内の各「許可」文は、指定されたコードソースにアクセス権のセットを与え、許可された処理を指定します。
次に、ポリシー構成ファイルの例を示します。
この構成ファイルは、ローカルファイルシステム上のgrant codeBase "file:/home/sysadmin/", signedBy "sysadmin" { permission java.security.SecurityPermission "insertProvider.*"; permission java.security.SecurityPermission "removeProvider.*"; permission java.security.SecurityPermission "putProviderProperty.*"; };/home/sysadmin/ディレクトリ内の署名された JAR ファイルからロードされたコードだけが、プロバイダの追加または削除、あるいはプロバイダのプロパティの設定ができることを示します。JAR ファイルの署名は、ユーザのキーストア内の別名sysadminで参照する公開鍵を使って検証できます。コードソースを指定する要素は、どちらも (または両方を) 省略可能です。次に、
codeBaseを省略した構成ファイルの例を示します。このポリシーが施行された場合、grant signedBy "sysadmin" { permission java.security.SecurityPermission "insertProvider.*"; permission java.security.SecurityPermission "removeProvider.*"; };sysadminによって署名された JAR ファイルのコードによるプロバイダの追加または削除が可能になります。JAR ファイルの場所は関係ありません。次に、署名者を省略した例を示します。
この場合、ローカルファイルシステムのgrant codeBase "file:/home/sysadmin/" { permission java.security.SecurityPermission "insertProvider.*"; permission java.security.SecurityPermission "removeProvider.*"; };/home/sysadmin/ディレクトリ内に置かれたコードは、プロバイダの追加と削除を行うことができます。コードに署名は必要ありません。
codeBaseとsignedByを両方とも省略した例を次に示します。この例では、コードソースを指定する要素がどちらも省略されています。したがって、出所がどこか、署名が付いているか、誰の署名が付いているかに関係なく、どのコードでもプロバイダの追加と削除が行えます。grant { permission java.security.SecurityPermission "insertProvider.*"; permission java.security.SecurityPermission "removeProvider.*"; };プロバイダの管理
次の表に、
Securityクラス内のメソッドのうち、インストールされているプロバイダを照会するために使用できるメソッドと、実行時にプロバイダをインストールまたは削除するためのメソッドの要約を示します。
プロバイダの照会 メソッド 説明 static Provider[] getProviders()インストールされているすべてのプロバイダを含む配列 (つまり、各パッケージプロバイダの Providerサブクラス) を返す。配列内のプロバイダの順序は、優先順位に従うstatic Provider getProvider
(String providerName)このメソッドは、 providerNameという名前のプロバイダを返す。このプロバイダが見つからないとnullを返す
プロバイダの追加 メソッド 説明 static int
addProvider(Provider provider)インストールされたプロバイダ一覧の末尾にプロバイダを追加する。プロバイダが追加された優先順位を返すか、すでにインストールされているためにプロバイダが追加されなかった場合は -1を返すstatic int insertProviderAt
(Provider provider, int position)指定された位置に新規のプロバイダを追加する。あるプロバイダが要求された場所にインストールされた場合は、それまでその場所にあったプロバイダ、および
positionよりあとの位置のすべてのプロバイダの順位は、1 つあとになり、一覧の最後尾に向かって 1 つ移動する。このメソッドは、プロバイダが追加された優先順位を返すか、すでにインストールされているためにプロバイダ が追加されなかった場合は-1を返す
プロバイダの削除 メソッド 説明 static void removeProvider(String name)指定した名前のプロバイダを削除する。プロバイダがインストールされていない場合は、何もせず復帰する。指定されたプロバイダが削除されると、そのプロバイダよりもあとの位置にあるすべてのプロバイダの位置が 1 つ前になり、インストールされたプロバイダ一覧の先頭に向かって 1 つ移動する
注: プロバイダの優先順位を変更する場合は、まず目的のプロバイダを削除してから、希望する優先順位の位置に挿入し直す必要があります。
セキュリティのプロパティ
Securityクラスは、システムに関するセキュリティのプロパティリストを保持します。これらのプロパティは、以下のメソッドを使って、信頼できるプログラムからアクセスして設定できます。static String getProperty(String key) static void setProperty(String key, String datum)
MessageDigest クラス
MessageDigestクラスはエンジンクラスで、安全な暗号化メッセージダイジェスト (SHA-1 や MD5 など) の機能を提供するように設計されています。安全な暗号化メッセージダイジェストは、任意サイズの入力 (バイト配列) を取り、固定サイズ出力を生成します。これを「ダイジェスト」または「ハッシュ」と言います。ダイジェストには次の 2 つの特徴があります。
- 計算によって、同じ値にハッシュされた 2 つのメッセージを検索できない
- ダイジェストの生成に使った入力情報を明らかにしない
メッセージダイジェストを使い、一意で、信頼できるデータ識別子を生成します。データ識別子をデータの「デジタル指紋」と呼ぶこともあります。
MessageDigestオブジェクトの生成ダイジェスト計算では、まず最初にメッセージダイジェストのインスタンスを生成します。どのエンジンクラスの場合も同様に、
MessageDigestクラスの static ファクトリメソッドgetInstanceを呼び出して、特定型のメッセージダイジェストアルゴリズムのMessageDigestオブジェクトを獲得します。static MessageDigest getInstance(String algorithm)
注: アルゴリズム名の大文字と小文字は区別されません。たとえば、次の呼び出しはすべて等価と見なされます。MessageDigest.getInstance("SHA-1") MessageDigest.getInstance("sha-1") MessageDigest.getInstance("sHa-1")
呼び出し側は、任意でプロバイダまたは
Providerインスタンスの名前を指定できます。プロバイダ名を指定すると、要求するアルゴリズムの実装を確実に指定プロバイダから取得できます。
static MessageDigest getInstance(String algorithm, String provider) static MessageDigest getInstance(String algorithm, Provider provider)
getInstanceを呼び出すと、初期化されたメッセージダイジェストオブジェクトが返ります。したがって、このあとで初期化を行う必要はありません。メッセージダイジェストオブジェクトのアップデート
データのダイジェストを計算するための次の手順は、初期化したメッセージダイジェストオブジェクトにデータを入れることです。これは、次のいずれかの
updateメソッドを呼び出すことによって実行します。
void update(byte input) void update(byte[] input) void update(byte[] input, int offset, int len)ダイジェストの計算
updateメソッドを呼び出してデータを入れたあとで、次のdigestメソッドのうちのどれか 1 つを使ってダイジェストを計算します。
byte[] digest() byte[] digest(byte[] input) int digest(byte[] buf, int offset, int len)最初の 2 つのメソッドは、計算されたダイジェストを返します。最後のメソッドは、オフセット位置
offsetから開始する提供バッファbuf内に算出ダイジェストを格納します。lenは、ダイジェストに割り当てられたbuf内のバイト数です。このメソッドは、実際にbuf内に格納されたバイト数を返します。入力バイトの配列を引数に取る
digestメソッドの呼び出しは、以下の呼び出しと等価です。入力を指定し、そのあとに引数を持たないvoid update(byte[] input)digestメソッドの呼び出しが続きます。詳細は、例を参照してください。
Signature クラスSignatureクラスはエンジンクラスで、DSA や MD5 を使う RSA などの暗号化デジタル署名機能を提供するように設計されています。安全な暗号化署名アルゴリズムは、任意サイズの入力と非公開鍵を取り、「署名」と呼ばれる比較的短い (固定サイズの場合もよくある) バイト文字列を生成します。このプロパティは次のとおりです。
- 署名の生成に使う非公開鍵に対応する公開鍵が与えられる。これは入力の認証性および整合性を検証できる
- 署名および公開鍵は、非公開鍵に関する情報を明らかにはしない
Signatureオブジェクトを使って、データに署名を付けることができます。また、指定の署名が、関連データの実際の認証署名かどうかを検証することもできます。 データの署名および検証の例は、例の項を参照してください。
Signatureオブジェクトの状態Signatureオブジェクトはモデルオブジェクトです。つまり、Signatureオブジェクトは、常に指定の状態にあり、この状態で 1 つの型の操作だけを実行できます。状態は、個々のクラスで定義した final (ファイナル) 整数の定数で表されます。
Signatureオブジェクトに可能な状態は、次の 3 つです。
UNINITIALIZEDSIGNVERIFYSignatureオブジェクトが初めて生成されるときは、UNINITIALIZEDの状態です。Signatureクラスは、状態をSIGNに変更するinitSignと、状態をVERIFYに変更するinitVerifyの 2 つの初期化メソッドを定義します。
Signatureオブジェクトの生成署名を付けたり、検証したりするには、最初にSignatureのインスタンスを生成します。どのエンジンクラスの場合も同様に、Signatureクラスの static ファクトリメソッドgetInstanceを呼び出して、特定型のメッセージ署名アルゴリズムのSignatureオブジェクトを獲得します。static Signature getInstance(String algorithm)呼び出し側は、任意でプロバイダまたは
注: アルゴリズム名の大文字と小文字は区別されません。
Providerクラスの名前を指定できます。プロバイダ名を指定すると、要求するアルゴリズムの実装を確実に指定プロバイダから取得できます。
static Signature getInstance(String algorithm, String provider) static Signature getInstance(String algorithm, Provider provider)
Signatureオブジェクトの初期化
Signatureオブジェクトを使うには、最初に必ずこれを初期化します。初期化メソッドは、オブジェクトを署名用に使うか検証用に使うかに応じて異なります。署名で使う場合、オブジェクトは最初に、署名を生成するエンティティの非公開鍵を使って初期化する必要があります。この初期化は、以下のメソッドを呼び出して実行します。
このメソッドでは、final void initSign(PrivateKey privateKey)SignatureオブジェクトはSIGN状態になります。
Signatureオブジェクトを検証で使う場合は、まず最初に、署名を検証するエンティティの公開鍵を使って初期化する必要があります。この初期化は、以下のいずれかのメソッドを呼び出して実行します。
final void initVerify(PublicKey publicKey) final void initVerify(Certificate certificate)このメソッドでは、
SignatureオブジェクトはVERIFY状態になります。署名
Signatureオブジェクトを署名用に初期化した場合 (このオブジェクトがSIGN状態の場合)、署名を付けるデータをオブジェクトに入れることができます。これは、以下のupdateメソッドのどれか 1 つを 1 回または複数回呼び出して実行します。
final void update(byte b) final void update(byte[] data) final void update(byte[] data, int off, int len)署名を付けるデータがすべて
Signatureオブジェクトに入るまで、updateメソッドを呼び出します。署名を生成するには、
signメソッドの 1 つを呼び出すだけです。final byte[] sign() final int sign(byte[] outbuf, int offset, int len)最初のメソッドは、署名の結果をバイト配列で返します。2 番目のメソッドは、オフセット位置 offset から開始する提供バッファ outbuf 内に署名の結果を格納します。len は、署名に割り当てられた outbuf 内のバイト数です。このメソッドは、実際に格納されたバイト数を返します。
署名の符号化は、アルゴリズムに依存します。Java 暗号化アーキテクチャでの ASN.1 符号化の使用方法については、「付録 B」を参照してください。
signメソッドを呼び出すと、signature (署名) オブジェクトは、initSignを呼び出して最初に署名用に初期化されたときの状態にリセットされます。つまり、オブジェクトをリセットするので、必要であればupdateとsignを呼び出して、同じ非公開鍵を使って別の署名を生成できます。あるいは異なる非公開鍵を指定し、
initSignへの新規呼び出しを作成したり、(署名を検証するためにSignatureオブジェクトを初期化する目的で)initVerifyへの新規呼び出しを作成したりできます。検証
Signatureオブジェクトを検証用に初期化した場合 (VERIFY状態にある場合) は、指定の署名が、それに関連したデータの実際の認証署名であるかどうかを検証できます。この処理を開始するには、検証データ (署名自体ではない) をオブジェクトに入れます。データは、次のいずれかのupdateメソッドを呼び出すことによってオブジェクトに渡されます。final void update(byte b) final void update(byte[] data) final void update(byte[] data, int off, int len)検証するデータがすべて
Signatureオブジェクトに入るまで、updateメソッドを呼び出します。これで、次のいずれかのverifyメソッドを呼び出して署名を検証できます。final boolean verify(byte[] signature) final boolean verify(byte[] signature, int offset, int length)引数は、署名を含むバイト配列である必要があります。引数は、署名を含むバイト配列である必要があります。このバイト配列は、前にいずれかの
signメソッドの呼び出しによって返された署名バイトを保持します。
verifyメソッドは、コード化した署名がupdateメソッドに入れたデータの認証署名かどうかを示すbooleanを返します。
verifyメソッドを呼び出すと、signature (署名) オブジェクトは、initVerifyを呼び出して検証用に初期化されたときの状態にリセットされます。つまり、オブジェクトをリセットするので、initVerifyへの呼び出しで指定した公開鍵を持つ識別の別の署名を検証できます。あるいは異なる非公開鍵を指定し、(異なるエンティティの署名を検証するために
Signatureオブジェクトを初期化する目的で)initVerifyへの新規呼び出しを作成したり、(署名を生成するためにSignatureオブジェクトを初期化する目的で)initSignへの新規呼び出しを作成したりできます。
アルゴリズムパラメータの仕様のインタフェースおよびクラス
アルゴリズムパラメータの仕様は、アルゴリズムとともに使われるパラメータのセットの透明な表現です。
パラメータのセットの「透明な」表現とは、セットの各パラメータの値に個別にアクセスできることを意味します。これらの値には、対応する仕様クラスに定義された
getメソッドの 1 つを使ってアクセスできます (たとえば、DSAParameterSpecでは、getP、getQ、およびgetGメソッドを定義して、それぞれp、q、およびgにアクセスする)。これに対して、
AlgorithmParametersクラスは「不透明な」表現を提供します。「不透明な」表現では、パラメータフィールドに直接アクセスできません。パラメータセットに関連付けられたアルゴリズム名の取得 (getAlgorithmによる)、およびそのパラメータセット用のある種の符号化の取得 (getEncodedによる) しかできません。以下は、
java.security.specパッケージに含まれるアルゴリズムパラメータ仕様のインタフェースおよびクラスの説明です。
AlgorithmParameterSpecインタフェースAlgorithmParameterSpecは、暗号化パラメータの透明な仕様へのインタフェースです。このインタフェースには、メソッドまたは定数が含まれていません。このインタフェースの唯一の目的は、すべてのパラメータの仕様をグループ化すること (およびそれらのパラメータに安全な型を提供すること) です。すべてのパラメータの仕様で、このインタフェースを実装する必要があります。
DSAParameterSpecクラスAlgorithmParameterSpecインタフェースを実装するこのクラスは、DSA アルゴリズムで使われるパラメータのセットを指定します。このクラスには、次のメソッドがあります。これらのメソッドは、DSA アルゴリズムパラメータであるプライムのBigInteger getP() BigInteger getQ() BigInteger getG()p、サブプライムのq、およびベースのgを返します。
AlgorithmParametersクラスAlgorithmParametersクラスは、暗号化パラメータの不透明な表現を提供するエンジンクラスです。「不透明な」表現では、パラメータフィールドに直接アクセスすることはできません。パラメータセットに関連付けられたアルゴリズム名の取得、およびそのパラメータセット用のある種の符号化の取得しかできません。これと対照的なのが、パラメータの「透明な」表現です。この場合、対応する仕様クラスで定義された
getメソッドの 1 つを使って、値に個々にアクセスできます。AlgorithmParametersにgetParameterSpecメソッドを呼び出して、AlgorithmParametersオブジェクトを透明な仕様に変換できます (以下を参照)。
AlgorithmParametersオブジェクトの作成どのエンジンクラスの場合も同様に、
AlgorithmParametersクラスの static ファクトリメソッドgetInstanceを呼び出して、特定型のアルゴリズムのAlgorithmParametersオブジェクトを獲得します。
static AlgorithmParameters getInstance(String algorithm)呼び出し側は、任意でプロバイダまたは
注: アルゴリズム名の大文字と小文字は区別されません。
Providerクラスの名前を指定できます。プロバイダ名を指定すると、要求するアルゴリズムパラメータの実装を確実に指定プロバイダから取得できます。static AlgorithmParameters getInstance(String algorithm, String provider) static AlgorithmParameters getInstance(String algorithm, Provider provider)
AlgorithmParametersオブジェクトの初期化
AlgorithmParametersオブジェクトのインスタンスが生成されたら、適切なパラメータの仕様またはパラメータの符号化を使って、initへの呼び出しによる初期化を行う必要があります。これらのvoid init(AlgorithmParameterSpec paramSpec) void init(byte[] params) void init(byte[] params, String format)initメソッドで、paramsは、符号化されたパラメータを含む配列で、formatは、復号化形式の名前です。params引数を指定し、format引数を指定しないinitメソッドでは、パラメータのプライマリ復号化形式が使われます。パラメータの ASN.1 仕様が存在する場合は、プライマリ復号化形式は、ASN.1 です。
注:AlgorithmParametersオブジェクトは、1 回だけ初期化できます。再利用はできません。
符号化されたパラメータの取得
AlgorithmParametersオブジェクトで表現されるパラメータのバイト符号化は、getEncodedへの呼び出しによって取得できます。このメソッドは、パラメータをプライマリ符号化形式で返します。この種のパラメータの ASN.1 仕様が存在する場合は、プライマリ復号化形式は、ASN.1 です。byte[] getEncoded()特定の形式でパラメータが返されるようにするには、次のように記述します。
byte[] getEncoded(String format)formatが null の場合は、ほかのgetEncodedメソッドと同様に、プライマリ復号化形式が使われます。
注: Sun プロバイダによって提供されるデフォルトの AlgorithmParameters の実装では、format引数は、現在のところ無視されます。
AlgorithmParametersオブジェクトから透明な仕様への変換アルゴリズムパラメータの透明なパラメータの仕様は、
getParameterSpecへの呼び出しにより、AlgorithmParametersオブジェクトから取得できます。AlgorithmParameterSpec getParameterSpec(Class paramSpec)paramSpecは、パラメータが返されるべき仕様クラスを識別します。たとえば、仕様クラスDSAPublicKeySpec.classが識別された場合、パラメータがDSAParameterSpecクラスのインスタンスに返されるべきであることを指示します。このクラスは、java.security.specパッケージに含まれます。
AlgorithmParameterGeneratorクラスAlgorithmParameterGeneratorクラスは、特定のアルゴリズム (AlgorithmParameterGeneratorのインスタンスの作成時に指定されるアルゴリズム) に適したパラメータのセットの生成に使用されるエンジンクラスです。
AlgorithmParameterGeneratorオブジェクトの作成どのエンジンクラスの場合も同様に、
AlgorithmParameterGeneratorクラスの static ファクトリメソッドgetInstanceを呼び出して、特定型のアルゴリズムのAlgorithmParameterGeneratorオブジェクトを獲得します。
static AlgorithmParameterGenerator getInstance( String algorithm)
注: アルゴリズム名の大文字と小文字は区別されません。
呼び出し側は、任意でプロバイダまたは
Providerクラスの名前を指定できます。プロバイダ名を指定すると、アルゴリズムパラメータジェネレータの実装を確実に指定プロバイダから取得できます。static AlgorithmParameterGenerator getInstance( String algorithm, String provider) static AlgorithmParameterGenerator getInstance( String algorithm, Provider provider)
AlgorithmParameterGeneratorオブジェクトの初期化
AlgorithmParameterGeneratorオブジェクトは、アルゴリズム独立型、またはアルゴリズム特定型の 2 種類の方法で初期化できます。アルゴリズム独立型の方法では、すべてのパラメータジェネレータが「サイズ」および乱数の発生源という概念を共有するという特性を利用します。サイズの単位は、すべてアルゴリズムパラメータで普遍的に共通していますが、その解釈はアルゴリズムにより異なります。たとえば、DSA アルゴリズムのパラメータの場合、「サイズ」はプライムモジュラスのビット数のサイズに一致します。特定のアルゴリズムのサイズについては、付録 B の「アルゴリズム」を参照してください。この方法を使うと、アルゴリズム特定型のパラメータの生成値が (ある場合は)、デフォルト基準値になります。 普遍的に共有されるこれら 2 つの引数の型をとる
initメソッドが 1 つあります。また、void init(int size, SecureRandom random)size引数だけをとり、システムが提供する乱数の発生源を使用するinitメソッドもあります。void init(int size)3 番目の方法では、パラメータジェネレータオブジェクトの初期化にアルゴリズム特定型のセマンティクスを使います。アルゴリズム特定型のセマンティクスは、
AlgorithmParameterSpecオブジェクト内に提供されるアルゴリズム特定型のパラメータ生成値のセットによって表されます。たとえば、Diffie-Hellman システムパラメータを生成するには、通常、パラメータ生成値は、プライムモジュラスおよびランダム指数のサイズで構成されます。どちらのサイズもビット数で指定します。Diffie-Hellman アルゴリズムは、JCE 1.2 から JCE の一部として提供されています。void init(AlgorithmParameterSpec genParamSpec, SecureRandom random) void init(AlgorithmParameterSpec genParamSpec)アルゴリズムパラメータの生成
AlgorithmParameterGeneratorオブジェクトを作成および初期化したら、generateParametersメソッドを使ってアルゴリズムパラメータを生成できます。AlgorithmParameters generateParameters()
Key インタフェース
Keyインタフェースは、すべての不透明な鍵に関するトップレベルのインタフェースです。すべての不透明な鍵オブジェクトが共有する機能を定義します。「不透明な」鍵の表現では、鍵を構成する鍵データに直接アクセスできません。つまり、「不透明」さにより、鍵へのアクセスが、
Keyインタフェースによって定義されるgetAlgorithm、getEncoded、およびgetFormatの 3 つのメソッドだけに制限されます。 これと対照的なのが「透明な」表現で、この場合は、対応する仕様クラス内に定義されたgetメソッドの 1 つを使って、各鍵データの値に個々にアクセスできます。不透明な鍵はすべて、次の 3 つの特性を持ちます。
鍵は一般的に、鍵ジェネレータ、証明書、鍵仕様 (
- アルゴリズム
- 鍵に対する鍵のアルゴリズムです。通常、鍵のアルゴリズムは、暗号化または非対称操作アルゴリズム (DSA や RSA など) で、これらのアルゴリズムや関連アルゴリズム (RSA を使う MD5、RSA を使う SHA-1 など) と連携して機能します。鍵のアルゴリズム名は、以下のメソッドを使って獲得します。
String getAlgorithm()- コード化形式
- 鍵の外部コード化形式は、鍵を別の組織に転送する場合など、鍵の標準表示が Java 仮想マシンの外部で必要なときに使います。鍵は標準形式 (X.509 や PKCS #8 など) に従ってコード化され、以下のメソッドを使って返されます。
byte[] getEncoded()- フォーマット
- コード化した鍵のフォーマット名です。以下のメソッドから返されます。
String getFormat()KeyFactoryを使用) または鍵管理で使うキーストアデータベースにアクセスするKeyStoreの実装から獲得します。
KeyFactoryを使って、アルゴリズム依存型の方法で符号化された鍵を解析することが可能です。また、
CertificateFactoryを使って、証明書を解析することも可能です。次に、
java.security.interfacesパッケージ内のKeyインタフェースを拡張するインタフェースのリストを示します。
PublicKeyおよびPrivateKeyインタフェース
PublicKeyおよびPrivateKeyインタフェースはどちらもKeyインタフェースを継承しますが、これらはメソッドを使わないインタフェースで、型の安全性および型の識別に使用します。
鍵仕様は、鍵を構成する鍵データの透明な表現です。鍵がハードウェアデバイス上に格納されている場合は、その鍵仕様には、デバイス上の鍵の識別を助ける情報が含まれていることがあります。
鍵の「透明な」表現とは、対応する仕様クラスで定義された
getメソッドの 1 つを使って、各鍵データに個々にアクセスできるということです。たとえば、DSAPrivateKeySpecは、getX、getP、getQ、およびgetGメソッドを定義して、非公開鍵xおよび鍵の計算に使用する DSA アルゴリズムのパラメータ (プライムのp、サブプライムのqおよびベースのg) にアクセスします。この表現と対照的なのが、
Keyインタフェースによって定義されるような、「不透明な」表現です。「不透明な」鍵の表現では、鍵要素フィールドに直接アクセスできません。つまり、「不透明」さにより、鍵へのアクセスが、Keyインタフェースによって定義されるgetAlgorithm、getEncoded、およびgetFormatの 3 つのメソッドだけに制限されます。鍵は、アルゴリズム特定型か、またはアルゴリズム独立型の符号化形式 (ASN.1 など) の方法で指定できます。たとえば、DSA 非公開鍵は、非公開鍵のコンポーネント
x、p、q、およびgによって指定するか (DSAPrivateKeySpecを参照)、または、非公開鍵の DER 符号化を使って指定することが可能です (PKCS8EncodedKeySpecを参照)。次に、
java.security.specパッケージ内に含まれる鍵仕様のインタフェースおよびクラスについて説明します。
KeySpecインタフェースこのインタフェースには、メソッドまたは定数が含まれていません。このインタフェースの唯一の目的は、すべての鍵仕様をグループ化することおよびそれらのグループに安全な型を提供することです。すべての鍵仕様で、このインタフェースを実装する必要があります。
DSAPrivateKeySpecクラスこのクラス (KeySpecインタフェースを実装) は、関連付けられたパラメータを使って DSA 非公開鍵を指定します。DSAPrivateKeySpecクラスには、次のメソッドがあります。これらのメソッドは、非公開鍵BigInteger getX() BigInteger getP() BigInteger getQ() BigInteger getG()x、および鍵の計算に使用される DSA アルゴリズムパラメータであるプライムのp、サブプライムのq、およびベースのgを返します。
DSAPublicKeySpecクラスこのクラス (KeySpecインタフェースを実装) は、関連付けられたパラメータを使って DSA 公開鍵を指定します。DSAPublicKeySpecクラスには、次のメソッドがあります。これらのメソッドは、公開鍵BigInteger getY() BigInteger getP() BigInteger getQ() BigInteger getG()y、および鍵の計算に使用される DSA アルゴリズムパラメータであるプライムのp、サブプライムのq、およびベースのgを返します。
RSAPrivateKeySpecクラスこのクラス (KeySpecインタフェースを実装) は、RSA 非公開鍵を指定します。RSAPrivateKeySpecクラスには、次のメソッドがあります。これらのメソッドは、RSA 非公開鍵を構成する RSA モジュラスBigInteger getModulus() BigInteger getPrivateExponent()nおよび非公開指数dの値を返します。
RSAPrivateCrtKeySpecクラスこのクラス (RSAPrivateKeySpecクラスを継承) は、PKCS #1 標準で定義されているように、中国剰余定理 (CRT) 情報の値を使って、RSA 非公開鍵を指定します。RSAPrivateCrtKeySpecクラスには、スーパークラスのRSAPrivateKeySpecから継承したメソッドのほかに、次のメソッドがあります。これらのメソッドは、公開指数BigInteger getPublicExponent() BigInteger getPrimeP() BigInteger getPrimeQ() BigInteger getPrimeExponentP() BigInteger getPrimeExponentQ() BigInteger getCrtCoefficient()eおよび CRT 情報の整数を返します。CRT 情報の整数は、モジュラスnの素因数p、nの素因数q、指数d mod (p-1)、指数d mod (q-1)、および中国剰余定理係数(q の逆数) mod pです。RSA 非公開鍵は、論理的にはモジュラスと非公開の指数だけで構成されます。CRT 値は、効率を向上させる目的で存在します。
RSAMultiPrimePrivateCrtKeySpecクラスこのクラス (RSAPrivateKeySpecクラスを継承) は、PKCS#1 v2.1 で定義されているように、中国剰余定理 (CRT) 情報の値を使って、RSA マルチプライム非公開鍵を指定します。RSAMultiPrimePrivateCrtKeySpecクラスには、スーパークラスのRSAPrivateKeySpecから継承したメソッドのほかに、次のメソッドがあります。これらのメソッドは、公開指数BigInteger getPublicExponent() BigInteger getPrimeP() BigInteger getPrimeQ() BigInteger getPrimeExponentP() BigInteger getPrimeExponentQ() BigInteger getCrtCoefficient() RSAOtherPrimeInfo[] getOtherPrimeInfo()eおよび CRT 情報の整数を返します。CRT 情報の整数は、モジュラスnの素因数p、nの素因数q、指数d mod (p-1)、指数d mod (q-1)、および中国剰余定理係数(q の逆数) mod pです。
getOtherPrimeInfoメソッドは、otherPrimeInfo(PKCS#1 v 2.1 に定義されている) を返すか、または、素因数が 2 つ (pおよびq) しかない場合は、null を返します。RSA 非公開鍵は、論理的にはモジュラスと非公開の指数だけで構成されます。CRT 値は、効率を向上させる目的で存在します。
RSAPublicKeySpecクラスこのクラス (KeySpecインタフェースを実装) は、RSA 公開鍵を指定します。RSAPublicKeySpecクラスには、次のメソッドがあります。これらのメソッドは、RSA 公開鍵を構成する RSA モジュラスBigInteger getModulus() BigInteger getPublicExponent()nおよび公開指数eの値を返します。
EncodedKeySpecクラスこの abstract クラス (KeySpecインタフェースを実装する) は、符号化された形式の公開鍵または非公開鍵を表します。そのgetEncodedメソッドは、次の符号化された鍵を返します。このクラスのabstract byte[] getEncoded();getFormatメソッドは、次の符号化形式の名前を返します。abstract String getFormat();具体的な実装
PKCS8EncodedKeySpecおよびX509EncodedKeySpecについては、次の節を参照してください。
PKCS8EncodedKeySpecクラスこのクラスは、EncodedKeySpecのサブクラスで、PKCS #8 標準で指定された形式に従って、非公開鍵の DER 符号化を表現します。 このクラスのgetEncodedメソッドは、PKCS #8 標準に従って符号化された鍵のバイトを返します。このクラスのgetFormatメソッドは、文字列 PKCS#8 を返します。
X509EncodedKeySpecクラスこのクラスは、EncodedKeySpecのサブクラスで、X.509 標準で指定された形式に従って、公開鍵の DER 符号化を表現します。 このクラスのgetEncodedメソッドは、X.509 標準に従って符号化された鍵のバイトを返します。このクラスのgetFormatメソッドは、文字列 X.509 を返します。
KeyFactory クラスKeyFactoryクラスは、不透明な暗号化鍵 (Key型) と、鍵仕様 (背後の鍵データの透明な表現) 間の変換を提供する目的で設計されたエンジンクラスです。鍵ファクトリは、双方向性があります。つまり、これによって、与えられた鍵仕様 (鍵のデータ) から不透明な鍵オブジェクトを構築することも、鍵オブジェクトの背後の鍵データを適切な形式で取得することもできます。
同一の鍵に対して、複数の互換性のある鍵仕様を存在させることもできます。たとえば、DSA 公開鍵は、コンポーネント
y、p、q、およびgによって指定することも (DSAPublicKeySpecを参照)、X.509 標準に従って DER 符号化を使って指定することもできます (X509EncodedKeySpecを参照)。鍵ファクトリは、互換性のある鍵仕様間の変換に使用できます。互換性のある鍵仕様間の変換では、鍵の構文解析が行われます。たとえば、
X509EncodedKeySpecをDSAPublicKeySpecに変換する場合は、基本的に符号化された鍵をコンポーネント単位で解釈処理します。例については、「鍵仕様およびKeyFactoryを使った署名の生成と検証」の最後を参照してください。
KeyFactoryオブジェクトの作成どのエンジンクラスの場合も同様に、
KeyFactoryクラスの static ファクトリメソッドgetInstanceを呼び出して、特定型の鍵アルゴリズムのKeyFactoryオブジェクトを獲得します。
static KeyFactory getInstance(String algorithm)呼び出し側は、任意でプロバイダまたは
注: アルゴリズム名の大文字と小文字は区別されません。
Providerクラスの名前を指定できます。プロバイダ名を指定すると、要求する鍵ファクトリの実装を確実に指定プロバイダから取得できます。static KeyFactory getInstance(String algorithm, String provider) static KeyFactory getInstance(String algorithm, Provider provider)鍵仕様と Key オブジェクト間の変換
公開鍵用の鍵仕様がある場合は、
generatePublicメソッドを使って、その仕様から不透明なPublicKeyオブジェクトを取得できます。PublicKey generatePublic(KeySpec keySpec)同様に、非公開鍵用の鍵仕様がある場合は、
generatePrivateメソッドを使って、その仕様から不透明なPrivateKeyオブジェクトを取得できます。PrivateKey generatePrivate(KeySpec keySpec)Key オブジェクトと鍵仕様間の変換
Keyオブジェクトがある場合は、getKeySpecメソッドの呼び出しによって、対応する鍵仕様を取得できます。KeySpec getKeySpec(Key key, Class keySpec)keySpecは、鍵のデータが返されるべき仕様クラスを識別します。たとえば、DSAPublicKeySpec.classは、鍵のデータがDSAPublicKeySpecクラスのインスタンスに返されるべきであることを指示します。詳細は、例を参照してください。
CertificateFactory クラスCertificateFactoryクラスは、証明書ファクトリの機能を定義するエンジンクラスです。証明書ファクトリは、証明書および証明書の取り消しリスト (CRL) オブジェクトをその符号化から生成するために使用されます。X.509 の証明書ファクトリは、
java.security.cert.X509Certificateのインスタンスである証明書、およびjava.security.cert.X509CRLのインスタンスである CRL を返します。
CertificateFactoryオブジェクトの作成どのエンジンクラスの場合も同様に、
CertificateFactoryクラスの static ファクトリメソッドgetInstanceを呼び出して、特定型の証明書または CRL のCertificateFactoryオブジェクトを獲得します。
static CertificateFactory getInstance(String type)呼び出し側は、任意でプロバイダまたは
注: 型の名前の大文字と小文字は区別されません。
Providerクラスの名前を指定できます。プロバイダ名を指定すると、要求する証明書ファクトリの実装を確実に指定プロバイダから取得できます。static CertificateFactory getInstance(String type, String provider) static CertificateFactory getInstance(String type, Provider provider)証明書オブジェクトの生成
証明書オブジェクトを生成し、入力ストリームから読み込まれたデータを使って初期化するには、generateCertificateメソッドを使います。特定の入力ストリームから読み込まれた証明書のコレクションビュー (空の可能性もある) を返すには、final Certificate generateCertificate(InputStream inStream)generateCertificatesメソッドを使います。final Collection generateCertificates(InputStream inStream)CRL オブジェクトの生成
(CRL) 証明書の取り消しリストオブジェクトを生成し、入力ストリームから読み込まれたデータを使って初期化するには、generateCRLメソッドを使います。特定の入力ストリームから読み込まれた CRL のコレクションビュー (空の可能性もある) を返すには、final CRL generateCRL(InputStream inStream)generateCRLsメソッドを使います。final Collection generateCRLs(InputStream inStream)
CertPathオブジェクトの生成CertPathオブジェクトを生成し、そのオブジェクトを入力ストリームから読み込まれたデータを使って初期化するには、次のいずれかのgenerateCertPathメソッドを使用します (必要に応じて、データに対して使用するエンコーディングを指定する)。final CertPath generateCertPath(InputStream inStream) final CertPath generateCertPath(InputStream inStream, String encoding)CertPathオブジェクトを生成し、証明書のリストを使用して初期化するには、次のメソッドを使用します。証明書ファクトリでサポートされているfinal CertPath generateCertPath(List certificates)CertPathエンコーディングのリストを取得するには、getCertPathEncodingsメソッドを呼び出します。初めにデフォルトのエンコーディングが一覧表示されます。final Iterator getCertPathEncodings()
KeyPair クラス
KeyPairクラスは鍵のペア (公開鍵と非公開鍵) の簡単なホルダーです。これには 2 つの public メソッドがあります。1 つは非公開鍵を返し、もう 1 つは公開鍵を返します。PrivateKey getPrivate() PublicKey getPublic()
KeyPairGenerator クラス
KeyPairGeneratorクラスはエンジンクラスで、公開鍵と非公開鍵のペアの生成に使います。鍵のペアの生成方法には、アルゴリズム独立型とアルゴリズム特定型の 2 つがあります。この 2 つの唯一の相違点は、オブジェクトの初期化にあります。
以下のメソッドの呼び出し例は、例の項を参照してください。
KeyPairGeneratorの生成すべての鍵のペアは、まず最初に
KeyPairGeneratorを使って生成します。この生成は、KeyPairGeneratorの以下のファクトリメソッドのどれか 1 つを使って実行します。
static KeyPairGenerator getInstance(String algorithm) static KeyPairGenerator getInstance(String algorithm, String provider) static KeyPairGenerator getInstance(String algorithm, Provider provider)
注: アルゴリズム名の大文字と小文字は区別されません。
KeyPairGeneratorの初期化特定のアルゴリズム用の鍵のペアのジェネレータは、そのアルゴリズムで使うことができる公開鍵または非公開鍵を作成します。また、アルゴリズム特定型のパラメータを生成された各鍵に関連付けます。まず、鍵のペアを初期化してからでなければ、鍵のペアは鍵を生成できません。ほとんどの場合、アルゴリズム独立型の初期化で十分です。ただし、アルゴリズム特定型の初期化を使用する必要のある場合もあります。
アルゴリズム独立型の初期化
すべての鍵ジェネレータは、キーサイズおよび乱数の発生源の概念を共有します。キーサイズは、アルゴリズムごとに解釈が異なります。たとえば、DSA アルゴリズムの場合、キーサイズはモジュラスの長さと一致します。特定のアルゴリズムのキーサイズについては、「付録 B: アルゴリズム」を参照してください。
普遍的に共有されるこれら 2 つの引数の型をとる
initializeメソッドがあります。また、void initialize(int keysize, SecureRandom random)keysize引数だけをとり、システムが提供する乱数の発生源を使用するinitializeメソッドもあります。void initialize(int keysize)上のアルゴリズム独立型
initializeメソッドを呼び出すときは、その他のパラメータは指定しないため、各鍵に関連付けられるアルゴリズム特定型のパラメータがある場合は、そのパラメータの処理は、プロバイダによって異なります。アルゴリズムが DSA アルゴリズムで、モジュラスのサイズ (キーサイズ) が 512、768、または 1024 の場合は、SUN プロバイダは
p、q、およびgパラメータ用に事前に計算した値を使います。モジュラスのサイズが上記の値の 1 つでない場合は、SUN プロバイダは、新しいパラメータのセットを作成します。これらの 3 つのモジュラスサイズ以外の、事前に計算されたパラメータセットを持つプロバイダが存在する可能性もあります。また、事前に計算されたパラメータがなく、常に新しいパラメータセットを作成するプロバイダが存在する可能性もあります。アルゴリズム特定型の初期化
アルゴリズム特定型パラメータのセットがすでに存在する状況では (DSA の「コミュニティパラメータ」など)、
AlgorithmParameterSpec引数をとるinitializeメソッドが 2 つあります。このうちの一方はSecureRandom引数もとりますが、他方では、乱数の発生源はシステムによって提供されます。詳細は例の項を参照してください。void initialize(AlgorithmParameterSpec params, SecureRandom random) void initialize(AlgorithmParameterSpec params)鍵のペアの生成
鍵のペアの生成手順は、初期化 (およびアルゴリズム) に関係なく、常に同じです。必ず
KeyPairGeneratorから以下のメソッドを呼び出します。KeyPair generateKeyPair()generateKeyPairを呼び出すたびに、異なる鍵のペアが作られます。
「キーストア」と呼ばれるデータベースは、鍵および証明書のリポジトリを管理するために使用できます。「証明書」は、あるエンティティからのデジタルに署名された文で、別のあるエンティティの公開鍵に特定の値が含まれていることを示します。キーストアの場所
キーストアは、デフォルトではユーザのホームディレクトリの
.keystoreという名前のファイルに格納されます。ユーザのホームディレクトリは、user.home システムプロパティによって決まります。Solaris システムの場合、user.home はデフォルトでユーザのホームディレクトリになっています。Win32 システムの場合、ユーザ名が「uName」の場合、user.home のデフォルトは次のように設定されます。
- C:\Winnt\Profiles\uName - マルチユーザ Windows NT システムの場合
- C:\Windows\Profiles\uName - マルチユーザ Windows 95/98/2000 システムの場合
- C:\Windows - シングルユーザ Windows 95/98/2000 システムの場合
キーストアの実装
KeyStoreクラスは、キーストア内の情報へのアクセスおよび情報の変更を行うための、明確に定義されたインタフェースを提供します。キーストアの固定実装としては、それぞれが特定の「タイプ」のキーストアを対象とする複数の異なる実装が存在可能です。キーストアを利用するコマンド行ツールには、
keytoolとjarsignerの 2 つがあります。 また、GUI ベースのpolicytoolというツールもあります。さまざまなソースのコードに対して (システムリソースへの) アクセス権を指定するポリシーファイルを処理する場合、このツールはPolicyのリファレンス実装によっても使われます。KeyStoreは public として使用可能なので、SDK ユーザはKeyStoreを使ったほかのセキュリティアプリケーションも作成できます。キーストアには、Sun が提供する組み込みのデフォルトの実装があります。これは、JKS という名前の独自のキーストアタイプ (形式) を利用するもので、キーストアをファイルとして実装しています。この実装では、個々の非公開鍵は個別のパスワードによって保護され、キーストア全体の完全性も (非公開鍵とは別の) パスワードによって保護されます。
キーストアの実装は、プロバイダベースです。具体的には、
KeyStoreが提供するアプリケーションインタフェースは、Service Provider Interface (SPI) という形で実装されています。つまり、対応するKeystoreSpi抽象クラス (これもjava.securityパッケージに含まれている) があり、このクラスが SPI のメソッドを定義しています。これらのメソッドは、「プロバイダ」が実装しなければなりません。「プロバイダ」とは、Java 2 SDK Security API によってアクセス可能なサービスのサブセットの固定実装を提供するパッケージまたはパッケージのセットのことです。したがって、キーストアの実装を提供するには、「Java(TM) 暗号化アーキテクチャ用プロバイダの実装方法」で説明しているように、クライアントが「プロバイダ」を実装し、KeystoreSpiサブクラスの実装を提供する必要があります。アプリケーションでは、
KeyStoreクラスのgetInstanceファクトリメソッドを使うことで、さまざまなプロバイダから異なる「タイプ」のキーストアの実装を選択できます。キーストアのタイプは、キーストア情報の格納形式とデータ形式を定義するとともに、キーストア内の非公開鍵とキーストア自体の完全性を保護するために使われるアルゴリズムを定義します。異なるタイプのキーストアの実装には、互換性はありません。キーストアのデフォルトタイプは、SUN プロバイダによって提供されるキーストア実装専用の jks です。これは、セキュリティプロパティファイル内の次の行によって指定されています。
ツールおよびほかのアプリケーションでデフォルト以外のキーストア実装を利用するには、この行を変更して別のタイプのキーストアを指定します。また、作成するツールおよびアプリケーションのユーザにキーストアのタイプを指定させて、その値をキーストアのkeystore.type=jksgetInstanceメソッドに渡すという方法もあります。最初の方法の例を次に示します。
pkcs12というタイプのキーストア実装を提供するプロバイダパッケージがある場合は、この行を次のように変更します。keystore.type=pkcs12
注: キーストアのタイプの指定では、大文字と小文字は区別されません。たとえば、JKS と jks は同じものとして扱われます。
KeyStoreクラスKeyStoreクラスは、キーストア内の情報へのアクセスおよび情報の変更を行うための明確に定義されたインタフェースを提供するエンジンクラスです。このクラスは、メモリ内の鍵および証明書のコレクションを表すもので、次の 2 種類のエントリを管理します。
キーストア内の各エントリは、「別名」文字列によって識別されます。非公開鍵とそれに関連付けられた証明連鎖の場合は、これらの文字列は、エンティティ自体が認証するというように、方法別に区別されます。たとえば、エンティティが異なる証明書発行局を使ったり、異なる公開鍵アルゴリズムを使ったりして、エンティティ自体を認証することも可能です。
- 鍵エントリ
このタイプのキーストアエントリには、非常に重要な暗号化鍵の情報が保持されます。情報は、保護された形式で格納され、権限のないアクセスを防ぎます。通常、この種類のエントリで格納される鍵は非公開鍵で、対応する公開鍵を証明する証明連鎖が伴います。
非公開鍵および証明連鎖は、デジタル署名を使った自己認証用に特定のエンティティが使用します。たとえば、ソフトウェア配布団体は、リリースまたはライセンスするソフトウェアの一部として JAR ファイルにデジタル署名を付けます。
- 信頼できる証明書エントリ
この種類のエントリには、別の組織に属する単一の公開鍵が含まれ、「信頼できる証明書」と呼ばれます。これは、キーストアの所有者が、証明書内の公開鍵が実際に証明書の「被認証者」(所有者) によって識別されたアイデンティティに属することを信頼するためです。
この種類のエントリは、ほかの組織の認証に使うことができます。
キーストアが持続性があるかどうか、および持続性がある場合に使われる機構は、ここでは指定されません。この規則により、重要な (秘密または非公開) 鍵を保護するためのさまざまな技術を使うことができます。スマートカードまたはその他の統合暗号化エンジン (SafeKeyper) を使うことも 1 つの方法です。また、ファイルなどのより単純な機構をさまざまな形式で使うこともできます。
主要な
KeyStoreメソッドを以下で説明します。
KeyStoreオブジェクトの作成ほかのエンジンクラスと同様に、
KeyStoreオブジェクトを取得するには、KeyStoreクラスのgetInstancestatic ファクトリメソッドを呼び出します。
static KeyStore getInstance(String type)呼び出し側は、任意でプロバイダまたは
Providerクラスの名前を指定できます。プロバイダ名を指定すると、要求するタイプの実装を確実に指定プロバイダから取得できます。
static KeyStore getInstance(String type, String provider) static KeyStore getInstance(String type, Provider provider)特定キーストアのメモリへのロード
KeyStoreオブジェクトを使う前に、loadメソッドによってメモリ内に実際のキーストアデータをロードする必要があります。オプションのパスワードを使って、キーストアデータの整合性をチェックします。パスワードが提供されない場合は、整合性のチェックは行われません。final void load(InputStream stream, char[] password)空のキーストアを作成するには、
InputStream引数としてnullをloadメソッドに渡します。キーストアの別名一覧の取得
キーストアエントリには、すべて一意の「別名」 (aliases) からアクセスします。
aliasesメソッドは、キーストア内の別名の列挙を返します。final Enumeration aliases()キーストアエントリの種類の決定
「キーストアクラス」で説明したように、キーストアのエントリには、2 種類あります。次のメソッドは、与えられた別名によって指定されたエントリが、それぞれ鍵または証明書か、信頼できる証明書エントリであることを決定します。
final boolean isKeyEntry(String alias) final boolean isCertificateEntry(String alias)キーストアエントリの追加、設定、および削除
setCertificateEntryメソッドは、証明書を指定された別名に割り当てます。final void setCertificateEntry(String alias, Certificate cert)aliasが存在しない場合は、その別名のついた信頼できる証明書のエントリが作成されます。aliasが存在し、信頼できる証明書のエントリが識別された場合は、それに関連付けられた証明書がcertによって置き換えられます。
setKeyEntryメソッドは、aliasがまだ存在しない場合に、鍵のエントリの追加または設定を行います。バイト配列としてfinal void setKeyEntry(String alias, Key key, char[] password, Certificate[] chain) final void setKeyEntry(String alias, byte[] key, Certificate[] chain)keyを取るメソッドでは、この引数は、保護された形式の鍵のバイトです。たとえば、Sun プロバイダによって提供されるキーストアの実装では、keyバイト配列は、PKCS #8 標準の定義に従ってEncryptedPrivateKeyInfoとして符号化された、保護された非公開鍵を格納します。もう一方のメソッドのpasswordは、鍵の保護に使うパスワードです。
deleteEntryメソッドは、エントリを削除します。final void deleteEntry(String alias)キーストアからの情報の取得
getKeyメソッドは、与えられた別名に関連付けられた鍵を返します。鍵は、与えられたパスワードを使って復元されます。次のメソッドは、与えられた別名に関連付けられた証明書、または証明連鎖をそれぞれ返します。final Key getKey(String alias, char[] password)次の文を使って、与えられた証明書と一致した最初のエントリの名前 (final Certificate getCertificate(String alias) final Certificate[] getCertificateChain(String alias)別名) を決定できます。final String getCertificateAlias(Certificate cert)キーストアの保存
メモリ内のキーストアを、storeメソッドを使って保存できます。パスワードは、キーストアデータの統合チェックサムの計算に使われます。統合チェックサムは、キーストアデータのあとに追加されます。final void store(OutputStream stream, char[] password)
SecureRandom クラス
SecureRandomクラスは、乱数ジェネレータの機能を提供するエンジンクラスです。
SecureRandomオブジェクトの作成ほかのエンジンクラスと同様に、SecureRandomオブジェクトを取得するには、SecureRandomクラスのgetInstancestatic ファクトリメソッドを呼び出します。
static SecureRandom getInstance(String algorithm)呼び出し側は、任意でプロバイダまたは
Providerクラスの名前を指定できます。プロバイダ名を指定すると、要求する乱数生成 (RNG) アルゴリズムの実装を確実に指定プロバイダから取得できます。static final SecureRandom getInstance(String algorithm, String provider) static final SecureRandom getInstance(String algorithm, Provider provider)
SecureRandomオブジェクトのシードまたは再シード呼び出し側が、
setSeedメソッドの 1 つへの呼び出しで、getInstanceメソッドへの呼び出しに従う場合以外は、SecureRandomの実装は、ジェネレータの内部状態自体を完全にランダム化しようとします。synchronized public void setSeed(byte[] seed) public void setSeed(long seed)SecureRandomオブジェクトに一度シードが入れられると、これはオリジナルのシードと同じようにランダムにビットを生成します。
SecureRandomオブジェクトは、setSeedメソッドの 1 つを使って常に再シードされる可能性があります。指定されたシードは、既存のシードと置き換えられるのではなく、既存のシードに追加されます。したがって、呼び出しを繰り返しても、ランダム性が減少しないことが保証されます。
SecureRandomオブジェクトの使い方ランダムバイトを得るには、呼び出し側は単純に任意の長さの配列を渡します。すると、この配列にランダムバイトが入ります。
synchronized public void nextBytes(byte[] bytes)シードバイトの生成
ほかの乱数ジェネレータにシードを入れる場合など、必要な場合は、generateSeedメソッドを呼び出して、与えられた数のシードバイトを生成できます。byte[] generateSeed(int numBytes)
Cipherクラスは、暗号化および暗号解読で使用される暗号機能を提供します。これは、JCE フレームワークのコア部分を構成します。Cipher オブジェクトの作成
API 内の他のエンジンクラスと同様、
CipherオブジェクトはCipherクラスのgetInstanceファクトリメソッドを使って作成されます。ファクトリメソッドは、クラスのインスタンスを返す static メソッドです。この場合は、要求された transformation を実装するCipherのインスタンスです。
Cipherオブジェクトを作成するには、変換名を指定する必要があります。要求された変換の実装を提供するプロバイダを指定することもできます。
public static Cipher getInstance(String transformation);
public static Cipher getInstance(String transformation,
String provider);変換名だけを指定すると、要求された変換の実装がその環境で使用可能かどうか、また複数の実装が存在する場合には優先度の高い実装が存在するかどうかをシステムが判別します。
変換名とパッケージプロバイダの両方を指定すると、システムは要求されたパッケージ内に要求された変換の実装が存在するかどうかを確認し、存在しない場合には例外をスローします。
"DES/CBC/PKCS5Padding"
"DES"Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");Cipher c1 = Cipher.getInstance("DES");このドキュメントの「付録 A」には、変換のアルゴリズム名、モード、およびパディング方式コンポーネントの指定に使用可能な標準名のリストが掲載されています。
ファクトリメソッドにより返されるオブジェクトは初期化されていないため、使用する前に初期化する必要があります。
Cipher オブジェクトの初期化
getInstanceを介して取得された Cipher オブジェクトは、次の 4 つのモードのいずれかで初期化する必要があります。これらのモードは、Cipherクラスの final (ファイナル) 整数の定数として定義されます。モードは、シンボル名で参照できます。以下に、各モードのシンボル名および目的を示します。
- ENCRYPT_MODE
データの暗号化- DECRYPT_MODE
データの暗号解読- WRAP_MODE
安全に転送するために鍵をラッピングする- UNWRAP_MODE
ラッピングされた鍵をjava.security.KeyオブジェクトにアンラッピングするCipher 初期化メソッドは、それぞれモードパラメータ (
opmode) をとり、そのモード用の Cipher オブジェクトを初期化します。他のパラメータには、鍵 (key) または鍵を含む証明書 (certificate)、アルゴリズムパラメータ (params)、および乱数の発生源 (random) が含まれます。Cipher オブジェクトを初期化する場合、次のいずれかの
initメソッドを呼び出します。public void init(int opmode, Key key);
public void init(int opmode, Certificate certificate)
public void init(int opmode, Key key,
SecureRandom random);
public void init(int opmode, Certificate certificate,
SecureRandom random)
public void init(int opmode, Key key,
AlgorithmParameterSpec params);
public void init(int opmode, Key key,
AlgorithmParameterSpec params,
SecureRandom random);
public void init(int opmode, Key key,
AlgorithmParameters params)
public void init(int opmode, Key key,
AlgorithmParameters params,
SecureRandom random)初期化ベクトルなどのパラメータを必要とする Cipher オブジェクトを暗号化用に初期化する場合、
initメソッドにパラメータを何も指定しないと、ランダムパラメータを生成するか、プロバイダ固有のパラメータセット (デフォルト) を使用することにより、基盤となる暗号実装が必須パラメータを提供すると見なされます。ただし、パラメータを必要とする Cipher オブジェクトを暗号解読用に初期化する場合、
initメソッドにパラメータを何も指定しないと、使用したinitメソッドに応じてInvalidKeyExceptionまたはInvalidAlgorithmParameterException例外が発生します。詳細は、「アルゴリズムパラメータの管理」に関するセクションを参照してください。
暗号解読には、暗号化に使用したのと同じパラメータを使用する必要があります。
Cipher オブジェクトを初期化すると、それまでに獲得した状態がすべて失われることに留意してください。つまり、Cipher を初期化することは、その Cipher の新規インスタンスを作成して初期化することと等価です。たとえば、指定された鍵で暗号解読を行うために Cipher を初期化してから、暗号化を行うために初期化すると、暗号解読モードで獲得した状態はすべて失われます。
データの暗号化および暗号解読
データの暗号化または暗号解読は、1 つのステップで実行 (「単一部分操作」) することも 、複数のステップで実行 (「複数部分操作」) することもできます。データの長さが不明な場合、またはデータが長すぎて一度にメモリに格納できない場合に、複数部分操作は有用です。
単独のステップでデータの暗号化または暗号解読を行う場合、次のいずれかの
doFinalメソッドを呼び出します。public byte[] doFinal(byte[] input);
public byte[] doFinal(byte[] input, int inputOffset,
int inputLen);
public int doFinal(byte[] input, int inputOffset,
int inputLen, byte[] output);
public int doFinal(byte[] input, int inputOffset,
int inputLen, byte[] output, int outputOffset)複数のステップでデータの暗号化または暗号解読を行うには、次のいずれかの
updateメソッドを呼び出します。public byte[] update(byte[] input);
public byte[] update(byte[] input, int inputOffset, int inputLen);
public int update(byte[] input, int inputOffset, int inputLen,
byte[] output);
public int update(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset)複数部分操作は、上記の
doFinalメソッドのいずれか (最後のステップで入力データが残される場合)、または次のdoFinalメソッドのいずれか (最後のステップで入力データが残らない場合) を使って終了させます。public byte[] doFinal();
public int doFinal(byte[] output, int outputOffset);指定された変換の一部としてパディング (またはアンパディング) が要求された場合、すべての
doFinalメソッドで、必要なパディング (またはアンパディング) 操作がすべて処理されます。
doFinalを呼び出すと、Cipher オブジェクトはinitを呼び出して初期化した時の状態にリセットされます。つまり、Cipher はリセットされて、データをさらに暗号化または暗号解読 (initの呼び出しで指定された操作モードに基づく) できるようになります。鍵のラッピングとアンラッピング
鍵をラッピングすると、ある場所から別の場所へ安全に転送できます。
wrap/unwrapAPI は鍵オブジェクトに対して直接機能するため、この API を使用するとコードの記述が容易になります。次のメソッドを使用すると、ハードウェアベースの鍵の安全な転送も可能になります。Key を wrap する場合、まず WRAP_MODE の Cipher オブジェクトを初期化し、次のメソッドを呼び出します。
public final byte[] wrap(Key key);ラップされた鍵のバイト (
wrapを呼び出した結果) を、そのラップを解除する他のユーザに提供する場合、受信者がunwrapを実行するのに必要な、次の追加情報も送信する必要があります。
- 鍵アルゴリズムの名前
- ラップされた鍵の型 (
Cipher.SECRET_KEY、Cipher.PRIVATE_KEY、またはCipher.PUBLIC_KEYのいずれか)鍵アルゴリズム名は、次に示すように Key インタフェースから
getAlgorithmメソッドを呼び出すことにより確認できます。public String getAlgorithm();
wrapへの呼び出しにより返されたバイトのラップを解除するには、UNWRAP_MODE の Cipher オブジェクトを初期化してから、以下を呼び出します。public final Key unwrap(byte[] wrappedKey,
String wrappedKeyAlgorithm,
int wrappedKeyType));ここで、
wrappedKeyはラップへの呼び出しにより返されたバイトを、wrappedKeyAlgorithmはラップされた鍵に関連付けられたアルゴリズムを、wrappedKeyTypeはラップされた鍵の型をそれぞれ指します。これは、Cipher.SECRET_KEY、Cipher.PRIVATE_KEY、またはCipher.PUBLIC_KEYのいずれかでなければなりません。アルゴリズムパラメータの管理
基盤となる Cipher 実装により使用されるパラメータ (アプリケーションにより
initメソッドに明示的に渡されたか、基盤となる実装自体により生成された) は、getParametersメソッドを呼び出すことにより Cipher オブジェクトから取得できます。このメソッドは、パラメータをjava.security.AlgorithmParametersオブジェクト (パラメータが使用されない場合はnull) として返します。パラメータが初期化ベクトル (IV) の場合、getIVメソッドを呼び出すことによりパラメータを取得できます。次の例では、パスワードベース暗号化を実装する Cipher オブジェクトを、パラメータを使用せずに鍵のみを使用して初期化します。ただし、選択されたパスワードベース暗号化用に選択されたアルゴリズムは、salt および iteration count という 2 つのパラメータを必要とします。これらは、基盤となるアルゴリズム実装自体により生成されます。アプリケーションは、生成されたパラメータを以下の方法で Cipher オブジェクトから取得できます。
import javax.crypto.*;
import java.security.AlgorithmParameters;
// get cipher object for password-based encryption
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
// initialize cipher for encryption, without supplying
// any parameters.Here, "myKey" is assumed to refer
// to an already-generated key.
c.init(Cipher.ENCRYPT_MODE, myKey);
// encrypt some data and store away ciphertext
// for later decryption
byte[] cipherText = c.doFinal("This is just an example".getBytes());
// retrieve parameters generated by underlying cipher
// implementation
AlgorithmParameters algParams = c.getParameters();
// get parameter encoding and store it away
byte[] encodedAlgParams = algParams.getEncoded();暗号解読には、暗号化に使用したのと同じパラメータを使用する必要があります。これらは、エンコーディングからインスタンス化することが可能であり、次に示すように、対応する Cipher オブジェクトを暗号解読用に初期化する際に使用できます。
import javax.crypto.*;
import java.security.AlgorithmParameters;
// get parameter object for password-based encryption
AlgorithmParameters algParams;
algParams =
AlgorithmParameters.getInstance("PBEWithMD5AndDES");
// initialize with parameter encoding from above
algParams.init(encodedAlgParams);
// get cipher object for password-based encryption
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
// initialize cipher for decryption, using one of the
// init() methods that takes an AlgorithmParameters
// object, and pass it the algParams object from above
c.init(Cipher.DECRYPT_MODE, myKey, algParams);Cipher オブジェクトの初期化時にパラメータを一切指定せず、基盤となる実装がいずれかのパラメータを使用するかどうか不明な場合、Cipher オブジェクトの
getParametersメソッドを呼び出して、返される値をチェックするだけで確認できます。返される値がnullの場合、パラメータが使用されなかったことを示します。SunJCE プロバイダにより実装される次の暗号アルゴリズムは、パラメータを使用します。
- DES、DES-EDE、および Blowfish は、フィードバック (つまり CBC、CFB、OFB、または PCBC) モードでの使用時に、初期化ベクトル (IV) を使用する。
javax.crypto.spec.IvParameterSpecクラスは、指定された IV での Cipher オブジェクトの初期化に使用できる- PBEWithMD5AndDES は、salt および iteration count で構成されるパラメータセットを使用する。
javax.crypto.spec.PBEParameterSpecクラスは、指定された salt および iteration count を使って PBEWithMD5AndDES を実装する Cipher オブジェクトを初期化する場合に使用できる
SealedObjectクラスを使用する場合、暗号解読操作に使用するアルゴリズムパラメータの格納または転送について心配する必要はありません。このクラスは、シール (暗号化) に使用されるパラメータを暗号化されたオブジェクトコンテンツに添付します。また、アンシール (暗号解読) でも同じパラメータを使用します。暗号出力時の考慮事項
Cipher の
updateおよびdoFinalの中には、呼び出し側による出力バッファの指定が可能なものがあります。暗号化または暗号解読されたデータは、このバッファ内に出力されます。この場合、暗号化または暗号解読操作の結果を保持できるだけの大きさのバッファを渡すことは重要です。Cipher 内の次のメソッドを使用して、設定すべき出力バッファのサイズを確認できます。
public int getOutputSize(int inputLen)
JCE に、セキュリティ保護されたストリームという概念が導入されました。これは、InputStream または OutputStream を Cipher オブジェクトと結び付けることにより実現されています。セキュリティ保護されたストリームは、
CipherInputStreamおよびCipherOutputStreamクラスにより提供されます。
CipherInputStream クラス
このクラスは、通過するデータの暗号化または暗号解読を行う
FilterInputStreamです。これは、InputStreamまたはそのサブクラスのいずれか、およびCipherで構成されます。CipherInputStream は、Cipher オブジェクトの挿入先の、セキュリティ保護された入力ストリームを表します。CipherInputStream のreadメソッドは、基盤となる InputStream から読み取られ、埋め込まれた Cipher オブジェクトによりさらに処理されたデータを返します。Cipher オブジェクトは、CipherInputStream で使用する前に完全に初期化する必要があります。たとえば、埋め込まれた Cipher が暗号解読用に初期化されている場合、CipherInputStream は基盤となる InputStream から読み込んだデータの暗号解読を試みてから、データをアプリケーションに返します。
このクラスは、上位クラス
java.io.FilterInputStreamおよびjava.io.InputStreamのセマンティクス (特にエラーに関するセマンティクス) に厳密に準拠します。このクラスは、上位クラスで指定されたメソッドを正確に保持し、それらすべてをオーバーライドします。このため、埋め込まれた暗号によるデータの追加処理が可能になります。さらに、このクラスは、上位クラスがスローしない例外をすべてキャッチします。特に、skip(long)メソッドは、Cipher により処理されたデータだけを無視します。このクラスを使用するプログラマにとって、このクラスが定義またはオーバーライドされていないメソッド (上位クラスのいずれかにあとで追加された新規メソッドまたはコンストラクタ) を使用しないようにすることは重要です。これらのメソッド実装は、CipherInputStream へのセキュリティ面の影響を考慮に入れていないためです。
使用方法の一例として、
cipher1が暗号化用に初期化されている場合を考えてみましょう。以下のコードは、暗号および FileInputStream を含む CipherInputStream を使用して、入力ストリームデータを暗号化する方法を示します。FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis;
fis = new FileInputStream("/tmp/a.txt");
cis = new CipherInputStream(fis, cipher1);
fos = new FileOutputStream("/tmp/b.txt");
byte[] b = new byte[8];
int i = cis.read(b);
while (i != -1) {
fos.write(b, 0, i);
i = cis.read(b);
}上記のプログラムは、ファイル
/tmp/a.txtからコンテンツを読み取って暗号化し、結果 (暗号化されたバイト) を/tmp/b.txtに格納します。次の例は、CipherInputStream および FileInputStream の複数インスタンスを簡単に接続する方法を示します。この例では、
cipher1およびcipher2が、それぞれ暗号化および暗号解読用に (対応する鍵を使用して) 初期化されているものとします。FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis1, cis2;
fis = new FileInputStream("/tmp/a.txt");
cis1 = new CipherInputStream(fis, cipher1);
cis2 = new CipherInputStream(cis1, cipher2);
fos = new FileOutputStream("/tmp/b.txt");
byte[] b = new byte[8];
int i = cis2.read(b);
while (i != -1) {
fos.write(b, 0, i);
i = cis2.read(b);
}上記のプログラムは、ファイル
/tmp/a.txtの内容を/tmp/b.txtにコピーします。ただし、/tmp/a.txtからの読み取り時に、最初に内容の暗号化、次に暗号解読が行われます。実際のところ、このプログラムはテキストを暗号化したあと、すぐに暗号解読を行うため、CipherInputStreams のチェーンをわかりやすく示す以外は特に有用なものではありません。CipherOutputStream クラス
このクラスは、通過するデータの暗号化または暗号解読を行う
FilterOutputStreamです。これは、OutputStreamまたはそのサブクラスのいずれか、およびCipherで構成されます。CipherOutputStream は、Cipher オブジェクトの挿入先の、セキュリティ保護された出力ストリームを表します。CipherOutputStream のwriteメソッドは、埋め込まれた Cipher オブジェクトを使ってデータを処理してから、基盤となる OutputStream にデータを書き出します。Cipher オブジェクトは、CipherOutputStream で使用する前に完全に初期化する必要があります。たとえば、埋め込まれた Cipher が暗号化用に初期化されている場合、CipherOutputStream はデータを暗号化してから、基盤となる出力ストリームに書き出します。
このクラスは、上位クラス
java.io.OutputStreamおよびjava.io.FilterOutputStreamのセマンティクス (特にエラーに関するセマンティクス) に厳密に準拠します。このクラスは、上位クラスで指定されたメソッドを正確に保持し、それらすべてをオーバーライドします。このため、埋め込まれた暗号によるすべてのデータの追加処理が可能になります。さらに、このクラスは、上位クラスがスローしない例外をすべてキャッチします。このクラスを使用するプログラマにとって、このクラスが定義またはオーバーライドされていないメソッド (上位クラスのいずれかにあとで追加された新規メソッドまたはコンストラクタ) を使用しないようにすることは重要です。これらのメソッド実装は、CipherOutputStream へのセキュリティ面の影響を考慮に入れていないためです。
使用方法の一例として、
cipher1が暗号化用に初期化されている場合を考えてみましょう。以下のコードは、暗号および FileOutputStream を含む CipherOutputStream を使用して、暗号化されたデータを出力ストリームに書き出す方法を示します。FileInputStream fis;
FileOutputStream fos;
CipherOutputStream cos;
fis = new FileInputStream("/tmp/a.txt");
fos = new FileOutputStream("/tmp/b.txt");
cos = new CipherOutputStream(fos, cipher1);
byte[] b = new byte[8];
int i = fis.read(b);
while (i != -1) {
cos.write(b, 0, i);
i = fis.read(b);
}
cos.flush();上記のプログラムは、ファイル
/tmp/a.txtからコンテンツを読み取って暗号化し、結果 (暗号化されたバイト) を/tmp/b.txtに格納します。次の例は、CipherOutputStream および FileOutputStream の複数インスタンスを簡単に接続する方法を示します。この例では、
cipher1およびcipher2が、それぞれ暗号解読および暗号化用に (対応する鍵を使用して) 初期化されているものとします。FileInputStream fis;
FileOutputStream fos;
CipherOutputStream cos1, cos2;
fis = new FileInputStream("/tmp/a.txt");
fos = new FileOutputStream("/tmp/b.txt");
cos1 = new CipherOutputStream(fos, cipher1);
cos2 = new CipherOutputStream(cos1, cipher2);
byte[] b = new byte[8];
int i = fis.read(b);
while (i != -1) {
cos2.write(b, 0, i);
i = fis.read(b);
}
cos2.flush();上記のプログラムは、ファイル
/tmp/a.txtの内容を/tmp/b.txtにコピーします。ただし、/tmp/b.txtに書き込む前に、内容の暗号化および暗号解読が行われます。このクラスの
flushとcloseメソッドには 1 つの重要な相違点があります。カプセル化された Cipher オブジェクトが、パディングを有効にしてブロック暗号アルゴリズムを実装する場合、この相違点に特に留意する必要があります。
flushは、カプセル化された Cipher オブジェクトにより処理済みのバッファリングされた出力バイトをすべて強制的に書き出すことにより、基盤となる OutputStream をフラッシュします。カプセル化された Cipher オブジェクトによりバッファリングされ、処理待ち状態にあるバイトは、書き出されません。
closeは、基盤となる OutputStream を閉じて、関連付けられたすべてのシステムリソースを解放します。カプセル化された Cipher オブジェクトのdoFinalメソッドを呼び出して、このオブジェクトによりバッファリングされたすべてのバイトを処理します。さらにflushメソッドを呼び出して、処理したバイトを基盤となるストリームに書き出します。
鍵ジェネレータは、対称アルゴリズム用の秘密鍵を生成します。
鍵ジェネレータの作成
API 内の他のエンジンクラスと同様、KeyGenerator オブジェクトは KeyGenerator クラスの
getInstanceファクトリメソッドを使って作成されます。ファクトリメソッドは、クラスのインスタンスを返す static メソッドです。この場合は、要求された鍵ジェネレータの実装を提供するKeyGeneratorのインスタンスです。
getInstanceは、秘密鍵を生成する対称アルゴリズムの名前を引数としてとります。オプションで、パッケージプロバイダ名を指定することもできます。public static KeyGenerator getInstance(String algorithm);
public static KeyGenerator getInstance(String algorithm,
String provider);アルゴリズム名だけを指定すると、要求された鍵ジェネレータの実装がその環境で使用可能かどうか、また複数の実装が存在する場合には優先度の高い実装が存在するかどうかをシステムが判別します。
アルゴリズム名とパッケージプロバイダの両方を指定すると、システムは要求されたパッケージ内に要求された鍵ジェネレータの実装が存在するかどうかを確認し、存在しない場合には例外をスローします。
KeyGenerator オブジェクトの初期化
特定の対称鍵アルゴリズムの鍵ジェレネータは、そのアルゴリズムで使用可能な対称鍵を作成します。また、生成された鍵に、アルゴリズムに特定のパラメータ (存在する場合) を関連付けます。
鍵の生成方法には、アルゴリズム独立型とアルゴリズム特定型の 2 つがあります。この 2 つの唯一の相違点は、オブジェクトの初期化にあります。
- アルゴリズム独立型の初期化
すべての鍵ジェネレータは、「キーサイズ」および「乱数の発生源」の概念を共有します。普遍的に共有されるこれら 2 つの引数の型をとる
initメソッドが存在します。また、keysize引数のみをとり、システムにより提供される乱数の発生源を使用するinitメソッドや、乱数の発生源だけをとるinitメソッドも存在します。public void init(SecureRandom random);
public void init(int keysize);
public void init(int keysize, SecureRandom random);上のアルゴリズムに依存しない
initメソッドを呼び出すときは、その他のパラメータは指定しないため、生成された鍵に関連付けられるアルゴリズムに特定のパラメータが存在する場合、そのパラメータの処理は、プロバイダによって異なります。- アルゴリズム特定型の初期化
アルゴリズムに特定のパラメータのセットがすでに存在する状況では、
AlgorithmParameterSpec引数をとるinitメソッドが 2 つあります。このうちの一方はSecureRandom引数もとりますが、他方では、乱数の発生源はシステムによって提供されます。public void init(AlgorithmParameterSpec params);
public void init(AlgorithmParameterSpec params,
SecureRandom random);クライアントが (
initメソッドの呼び出しを介して) KeyGenerator を明示的に初期化しない場合、各プロバイダはデフォルトの初期化を提供およびドキュメント化する必要があります。鍵の作成
次のメソッドにより、秘密鍵が生成されます。public SecretKey generateKey();
このクラスは、秘密鍵のファクトリを表します。
鍵ファクトリは、「鍵」(
java.security.Key型の不透明な暗号化鍵) を「鍵仕様」(背後の鍵データの適切な形式の透明表現) に変換したり、その逆の変換を行うために使用します。
javax.crypto.SecretKeyFactoryオブジェクトは、秘密 (対称) 鍵のみを処理するのに対し、java.security.KeyFactoryオブジェクトは鍵ペアの公開鍵および非公開鍵コンポーネントを処理します。
java.security.Key型のオブジェクト (java.security.PublicKey、java.security.PrivateKey、およびjavax.crypto.SecretKeyはそのサブクラス) は、その実装方法が不明であるため、不透明な鍵オブジェクトになります。基盤となる実装はプロバイダ依存であるため、ソフトウェアベースにもハードウェアベースにもできます。鍵ファクトリを使用すると、プロバイダは独自の暗号化鍵実装を提供できるようになります。たとえば、公開値
y、プライム係数p、ベースgで構成される Diffie Hellman 公開鍵の鍵仕様を保持しており、同じ仕様を別のプロバイダの Diffie-Hellman 鍵ファクトリに送る場合、生成されるPublicKeyオブジェクトはたいてい、異なる基盤実装を保持するようになります。プロバイダは、秘密鍵ファクトリがサポートする鍵仕様をドキュメント化する必要があります。たとえば、「SunJCE」プロバイダにより提供される DES 鍵の
SecretKeyFactoryは、DESKeySpecを DES 鍵の透明表現としてサポートします。また、DES-EDE 鍵のSecretKeyFactoryはDESedeKeySpecを DES-EDE 鍵の透明表現として、PBE のSecretKeyFactoryはPBEKeySpecを基盤となるパスワードの透明表現として、それぞれサポートします。次の例は、
SecretKeyFactoryを使用して秘密鍵データをSecretKeyオブジェクトに変換する方法を示します。これは、以降のCipher操作で使用できます。// Note the following bytes are not realistic secret key data
// bytes but are simply supplied as an illustration of using data
// bytes (key material) you already have to build a DESKeySpec.
byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03,
(byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };
DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);この場合、
secretKeyの基盤実装は、keyFactoryのプロバイダに基づきます。別の方法として、プロバイダに依存せずに、同じ鍵データから等価な機能を持つ
SecretKeyオブジェクトを作成することも可能です。その場合、javax.crypto.SecretKeyインタフェースを実装するjavax.crypto.spec.SecretKeySpecクラスを使用します。byte[] desKeyData = { (byte)0x01, (byte)0x02, ...};
SecretKeySpec secretKey = new SecretKeySpec(desKeyData, "DES");
プログラマは、このクラスを使用してオブジェクトを作成し、暗号化アルゴリズムを利用してその機密性を保護することができます。
java.io.Serializableインタフェースを実装するオブジェクトが指定された場合、元のオブジェクトを直列化形式 (「ディープコピー」) でカプセル化するSealedObjectを作成し、DES などの暗号化アルゴリズムを使用して直列化された内容をシール (暗号化) することにより、機密性を保護できます。その後、暗号化された内容の暗号解読 (適正な暗号解読鍵を使用)、および直列化解除を行うことにより、元のオブジェクトを復元できます。一般的な使用法を、次のコード例に示します。オブジェクトをシールする場合、シール対象のオブジェクトから
SealedObjectを作成し、直列化されたオブジェクト内容を暗号化する、完全に初期化されたCipherオブジェクトを作成します。この例では、文字列「This is a secret」が DES アルゴリズムを使用してシールされます。シール操作に使用されるすべてのアルゴリズムパラメータは、SealedObjectの内部に格納されることに留意してください。// create Cipher object
// Note:sKey is assumed to refer to an already-generated
// secret DES key.
Cipher c = Cipher.getInstance("DES");
c.init(Cipher.ENCRYPT_MODE, sKey);
// do the sealing
SealedObject so = new SealedObject("This is a secret", c);シールされた元のオブジェクトは、次の異なる 2 つの方法で復元可能です。
- 厳密に同一のアルゴリズム、鍵、パディング方式などで初期化され、オブジェクトのシールに使用された
Cipherオブジェクトを使用する方法c.init(Cipher.DECRYPT_MODE, sKey);
try {
String s = (String)so.getObject(c);
} catch (Exception e) {
// do something
};この方法には、暗号解読鍵に関する知識がなくても、シールされたオブジェクトのアンシールを実行できるという利点があります。たとえば、あるパーティが暗号オブジェクトを必須の暗号解読鍵を使って初期化したあとで、別のパーティに渡すと、そのパーティはシールされたオブジェクトをアンシールできます。
- 適切な暗号解読鍵を使用する方法 (DES は対称暗号化アルゴリズムであるため、シールとアンシールに同じ鍵を使用できる)
try {
String s = (String)so.getObject(sKey);
} catch (Exception e) {
// do something
};この方法では、
getObjectメソッドは、適切な暗号解読アルゴリズム用の暗号オブジェクトを作成し、シール済みのオブジェクトに格納された暗号解読鍵およびアルゴリズムパラメータ (存在する場合) を使用して初期化を行います。この方法の利点は、オブジェクトをアンシールするパーティが、オブジェクトのシールに使用したパラメータ (例: IV) を追跡する必要がないことです。
KeyAgreement クラスは、鍵協定プロトコルの機能を提供します。共有の秘密作成に関係する鍵は、
KeyPairGeneratorまたはKeyGeneratorのいずれかの鍵ジェネレータか、KeyFactoryにより、または鍵協定プロトコルの中間フェーズの結果として作成されます。KeyAgreement オブジェクトの作成
鍵協定に関係する各パーティは、KeyAgreement オブジェクトを作成する必要があります。API 内の他のエンジンクラスと同様、KeyAgreement オブジェクトは KeyAgreement クラスの
getInstanceファクトリメソッドを使って作成されます。ファクトリメソッドは、クラスのインスタンスを返す static メソッドです。この場合は、要求された鍵協定アルゴリズムを提供するKeyAgreementのインスタンスです。
getInstanceは、引数として鍵協定アルゴリズムの名前をとります。オプションで、パッケージプロバイダ名を指定することもできます。public static KeyAgreement getInstance(String algorithm);
public static KeyAgreement getInstance(String algorithm,
String provider);アルゴリズム名だけを指定すると、要求された鍵協定の実装がその環境で使用可能かどうか、また複数の実装が存在する場合には優先度の高い実装が存在するかどうかをシステムが判別します。
アルゴリズム名とパッケージプロバイダの両方を指定すると、システムは要求されたパッケージ内に要求された鍵協定の実装が存在するかどうかを確認し、存在しない場合には例外をスローします。
KeyAgreement オブジェクトの初期化
非公開情報を使用して KeyAgreement オブジェクトを初期化できます。Diffie-Hellman の場合、Diffie-Hellman 非公開鍵を使用して初期化します。補足的な初期化情報には、乱数の発生源、アルゴリズムパラメータのセットが含まれます。要求された鍵協定アルゴリズムで、アルゴリズムパラメータを指定する必要があり、また KeyAgreement オブジェクトの初期化にパラメータではなく鍵だけが提供される場合、必須のアルゴリズムパラメータを鍵に含める必要があります。たとえば、Diffie-Hellman アルゴリズムは、プライム係数
pおよびベースジェネレータgをパラメータとして使用します。KeyAgreement オブジェクトを初期化する場合、次のいずれかの
initメソッドを呼び出します。public void init(Key key);
public void init(Key key, SecureRandom random);
public void init(Key key, AlgorithmParameterSpec params);
public void init(Key key, AlgorithmParameterSpec params,
SecureRandom random);KeyAgreement フェーズの実行
各協定プロトコルは、鍵協定に関係する各パーティが実行する必要のある多数のフェーズで構成されます。
鍵協定の次のフェーズを実行するには、
doPhaseメソッドを呼び出します。public Key doPhase(Key key, boolean lastPhase);
keyパラメータには、そのフェーズで処理する鍵が含まれます。たいていの場合、これは、鍵協定に関係する他のパーティのいずれかの公開鍵、または前のフェーズで生成された中間鍵です。doPhaseは、この鍵協定の他のパーティに送信する必要のある中間鍵を返すため、続くフェーズでその鍵を処理できます。
lastPhaseパラメータには、実行するフェーズが鍵協定の最後のフェーズかどうかを指定します。値FALSEは、これが鍵協定の最後のフェーズではない (このあとにフェーズが続く) ことを示します。値TRUEは、これが鍵協定の最後のフェーズであり、鍵協定が完了する (次にgenerateSecretが呼び出される) ことを示します。Diffie-Hellman で 2 つのパーティが存在する場合 (「付録 F」を参照)、
lastPhaseをTRUEに設定してdoPhaseを呼び出します。Diffie-Hellman で 3 つのパーティが存在する場合、doPhaseを 2 度呼び出します。最初はlastPhaseをFALSEに設定し、2 度目にはlastPhaseをTRUEに設定します。共有される秘密の生成
各パーティがすべての必須鍵協定フェーズを実行したあとで、
generateSecretメソッドのいずれかを呼び出して共有される秘密を計算できます。public byte[] generateSecret();
public int generateSecret(byte[] sharedSecret, int offset);
public SecretKey generateSecret(String algorithm);
Mac クラスは、メッセージ認証コード (MAC) の機能を提供します。「付録 F」の「コード例」を参照してください。
Mac オブジェクトの作成
API 内の他のエンジンクラスと同様、Mac オブジェクトは Mac クラスの
getInstanceファクトリメソッドを使って作成されます。ファクトリメソッドは、クラスのインスタンスを返す static メソッドです。この場合は、要求された MAC アルゴリズムを提供するMacのインスタンスです。
getInstanceは、引数として Mac アルゴリズムの名前をとります。オプションで、パッケージプロバイダ名を指定することもできます。public static Mac getInstance(String algorithm);
public static Mac getInstance(String algorithm,
String provider);アルゴリズム名だけを指定すると、要求された MAC アルゴリズムの実装がその環境で使用可能かどうか、また複数の実装が存在する場合には優先度の高い実装が存在するかどうかをシステムが判別します。
アルゴリズム名とパッケージプロバイダの両方を指定すると、システムは要求されたパッケージ内に要求された MAC アルゴリズムの実装が存在するかどうかを確認し、存在しない場合には例外をスローします。
Mac オブジェクトの初期化
Mac オブジェクトは、常に (秘密) 鍵を使って初期化されます。また、基盤となる MAC アルゴリズムによっては、パラメータセットを使って初期化することもできます。
Mac オブジェクトを初期化する場合、次のいずれかの
initメソッドを呼び出します。public void init(Key key);
public void init(Key key, AlgorithmParameterSpec params);
javax.crypto.SecretKeyインタフェースを実装する任意の (秘密) 鍵オブジェクトを使って、Mac オブジェクトを初期化できます。これは、javax.crypto.KeyGenerator.generateKey()が返すオブジェクト、javax.crypto.KeyAgreement.generateSecret()などが返す鍵協定プロトコルの結果生成されるオブジェクト、またはjavax.crypto.spec.SecretKeySpecのインスタンスです。MAC アルゴリズムの中には、Mac オブジェクトの初期化に使用される (秘密) 鍵オブジェクトに関連付けられた (秘密) 鍵アルゴリズムが重要ではないものがあります (SunJCE プロバイダの HMAC-MD5 および HMAC-SHA1 実装の場合)。ただし、それ以外の場合、(秘密) 鍵アルゴリズムは重要であり、(秘密) 鍵オブジェクトが不適切な (秘密) 鍵アルゴリズムで使用されると、
InvalidKeyExceptionがスローされます。MAC の計算
MAC は、1 つのステップで計算 (「単一部分操作」) することも 、複数のステップで計算 (「複数部分操作」) することもできます。データの長さが不明な場合、またはデータが長すぎて一度にメモリに格納できない場合に、複数部分操作は有用です。
あるデータの MAC を 1 回のステップで計算するには、次の
doFinalメソッドを呼び出します。public byte[] doFinal(byte[] input);複数のステップでデータの MAC を計算するには、次のいずれかの
updateメソッドを呼び出します。public void update(byte input);
public void update(byte[] input);
public void update(byte[] input, int inputOffset, int inputLen);複数部分操作は、上記の
doFinalメソッド (最後のステップで入力データが残される場合)、または次のdoFinalメソッドのいずれか (最後のステップで入力データが残らない場合) を使って終了させます。public byte[] doFinal();
public void doFinal(byte[] output, int outOffset);
注 1: 大半のアプリケーション開発者には、このセクションで説明する内容は関係ありません。関係があるのは、作成するアプリケーションが、政府により暗号化制限の課された国に輸出される可能性があり、アプリケーションをその制限に適合させる必要がある場合だけです。注 2: このセクション全体で、「アプリケーション」という語は、アプリケーションとアプレットの両方を指します。Java 2 SDK, v 5.0 の JCE フレームワークには、異なる管轄コンテキスト (位置) のアプレット/アプリケーションから利用可能な暗号化アルゴリズムおよび最大暗号化強度に関する制限を施行する機能が含まれます。これらの制限はすべて、「管轄ポリシーファイル」に指定されます。
輸入管理制限があるため、Java 2 SDK, v 5.0 に同梱された管轄ポリシーファイルは「強固」ですが、暗号化の使用には制限があります。適格国 (大半の国が該当) の在住者は、暗号化機能に制限のない「強度無制限」のバージョンを利用できます。ただし、政府が制限を課しているこれらの国が輸入できるのは「強力な」バージョンだけです。JCE フレームワークでは、インストール済みの管轄ポリシーファイルで指定された制限が施行されます。
これらの国の一部またはすべてで、特定のアプリケーションに対し、暗号化制限の一部またはすべての免責が許可されています。たとえば、特定の種類のアプリケーションは「特別」と見なされ、免責されます。また、鍵復元などの「免責機構」を利用するアプリケーションは、免責可能です。この種の国では、免責されたと見なされるアプリケーションは、免責されていないアプリケーションに許可されるよりも強力な暗号化にアクセスできます。
実行時にアプリケーションが「免責されている」と認識されるようにするには、次の条件を満たす必要があります。
- JAR ファイル内にアクセス権ポリシーファイルを保持する必要がある。アクセス権ポリシーファイルには、アプリケーションが保持する暗号化関連のアクセス権、およびそれを保持する条件 (存在する場合) を指定する
- アプリケーションおよびアクセス権ポリシーファイルを含む JAR ファイルには、アプリケーションが免責を受け取ったあとで発行されたコード署名証明書を使用して署名する必要がある
以下に、暗号化制限の一部またはすべての免責をアプリケーションに設定するために必要な手順のサンプルを示します。これは、免責されたものとしてアプリケーションを認識および処理するため、JCE により要求される情報を含む、基本情報です。実際には、アプリケーションを実行可能にする (政府が暗号化制限を課している) 特定の国の免責要件を知る必要があります。また、免責されたアプリケーションの処理プロセスを保持する JCE フレームワークベンダーの要件も理解しておく必要があります。詳細は、ベンダーにお尋ねください。なお、SunJCE プロバイダは、ExemptionMechanismSpi クラスの実装を提供しません。
- ステップ 1: アプリケーションコードの記述およびコンパイル
- ステップ 2: 適切な暗号化アクセス権を付与するアクセス権ポリシーファイルの作成
- ステップ 3: テストの準備
- ステップ 3a: 政府の課す制限に関する政府承認の申請
- ステップ 3b: コード署名証明書の取得
- ステップ 3c: アプリケーションおよびアクセス権ポリシーファイルの JAR ファイルへのバンドル
- ステップ 3d: JAR ファイルへの署名
- ステップ 3e: 制限国のユーザと同じ環境の設定
- ステップ 3f: アクセス権ポリシーファイルで指定された免責機構を実装するプロバイダのインストール (免責機構を使用するアプリケーションのみ)
- ステップ 4: アプリケーションのテスト
- ステップ 5: 米国政府による輸出承認の申請 (必要な場合)
- ステップ 6: アプリケーションの配備
免責機構を使用するアプリケーションに対する特殊コード要件
アプリケーションが関連付けられたアクセス権ポリシーファイルを (同じ JAR ファイル内に) 保持し、アクセス権ポリシーファイルで免責機構が指定されている場合、Cipher
getInstanceメソッドが呼び出されて Cipher がインスタンス化されると、JCE コードはインストール済みのプロバイダ内で指定された免責機構を実装するものを検索します。目的のプロバイダが見つかると、JCE は、プロバイダの実装に関連付けられた ExemptionMechanism API オブジェクトをインスタンス化してから、ExemptionMechanism オブジェクトをgetInstanceが返す Cipher と関連付けます。Cipher をインスタンス化したあと、かつ初期化する前に (Cipher
initメソッドを呼び出して)、コードから次の Cipher メソッドを呼び出す必要があります。public ExemptionMechanism getExemptionMechanism()この呼び出しにより、Cipher に関連付けられた ExemptionMechanism オブジェクトが返されます。次に、返された ExemptionMechanism に対して次のメソッドを実行して、免責機構の実装を初期化する必要があります。
public final void init(Key key)ここで指定する引数の型は、このあとで Cipher
initメソッドに指定する引数の型と同じにする必要があります。ExemptionMechanism の初期化が完了したら、通常と同じ方法で Cipher を初期化して使用できます。
アクセス権ポリシーファイル
実行時にアプリケーションが暗号化制限の一部またはすべてを「免責」されていると認識されるには、JAR ファイル内にアクセス権ポリシーファイルをバンドルする必要があります。アクセス権ポリシーファイルには、アプリケーションが保持する暗号化関連のアクセス権、およびそれを保持する条件 (存在する場合) を指定します。
注: アプリケーションにバンドルするアクセス権ポリシーファイルの名前は、
cryptoPermsにする必要があります。免責されるアプリケーションにバンドルされるアクセス権ポリシーファイル内のアクセス権エントリの書式は、Java 2 SDK, v 5.0 とともにダウンロードされる管轄ポリシーファイルの書式と同じです。以下にその書式を示します。
permission <crypto permission class name>[ <alg_name>
[[, <exemption mechanism name>][, <maxKeySize>
[, <AlgorithmParameterSpec class name>,
<parameters for constructing an AlgorithmParameterSpec object>]]]];管轄ポリシーファイルの書式の詳細は、「付録 D」を参照してください。
免責されるアプリケーションのアクセス権ポリシーファイル
アプリケーションの中には、制限を完全に解除可能なものもあります。通常、その種のアプリケーションにバンドルするアクセス権ポリシーファイルには、以下を含めるだけで十分です。
grant {
// There are no restrictions to any algorithms.
permission javax.crypto.CryptoAllPermission;
};アプリケーションが 1 つ (またはいくつかの特定の) アルゴリズムだけを使用する場合、アクセス権ポリシーファイルには、CryptoAllPermission を付与するのではなく、そのアルゴリズムを明示的に記述します。たとえば、アプリケーションが Blowfish アルゴリズムだけを使用する場合、アクセス権ポリシーファイルですべてのアルゴリズムに CryptoAllPermission を付与する必要はありません。Blowfish アルゴリズムが使用される場合、暗号化制限が存在しないことを指定するだけで十分です。この場合、アクセス権ポリシーファイルは、次のようになります。
grant {
permission javax.crypto.CryptoPermission "Blowfish";
};免責機構により免責されるアプリケーションのアクセス権ポリシーファイル
免責機構が導入されるためにアプリケーションが「免責される」と見なされる場合、アプリケーションにバンドルされるアクセス権ポリシーファイルに 1 つ以上の免責機構を指定する必要があります。実行時に、これらの免責機構のいずれかが機能していると、アプリケーションは免責されたものと見なされます。次のようなアクセス権エントリ内に、各免責機構を指定する必要があります。
// No algorithm restrictions if specified
// exemption mechanism is enforced.
permission javax.crypto.CryptoPermission *,
"<ExemptionMechanismName>";ここで、
<ExemptionMechanismName>には免責機構の名前を指定します。指定可能な免責機構の名前には、以下が含まれます。例として、鍵復元または鍵エスクローのいずれかが機能すると、アプリケーションが免責される場合を考えましょう。その場合、アクセス権ポリシーファイルには、以下が含まれます。
- KeyRecovery
- KeyEscrow
- KeyWeakening
grant {
// No algorithm restrictions if KeyRecovery is enforced.
permission javax.crypto.CryptoPermission *,
"KeyRecovery";
// No algorithm restrictions if KeyEscrow is enforced.
permission javax.crypto.CryptoPermission *,
"KeyEscrow";
};注: 免責機構を指定するアクセス権エントリには、最大キーサイズを指定してはなりません。許可される鍵のサイズは、実際にはインストールされた免責管轄ポリシーファイルにより決定されます。詳細は、次のセクションを参照してください。
バンドルされたアクセス権ポリシーファイルによる暗号化アクセス権への影響
実行時にアプリケーションが Cipher をインスタンス化し (
getInstanceメソッドを呼び出して)、かつそのアプリケーションが関連するアクセス権ポリシーファイルを保持する場合、JCE はアクセス権ポリシーファイルにgetInstanceの呼び出しで指定されたアルゴリズムに適用されるエントリが含まれるかどうかをチェックします。該当するエントリが含まれ、エントリが CryptoAllPermission を付与するか免責機構の実施を指定しない場合、このアルゴリズムには暗号化制限が存在しないことを意味します。アクセス権ポリシーファイルに
getInstanceの呼び出しで指定されたアルゴリズムに適用されるエントリが含まれ、かつエントリで免責機構の実施が指定されている場合、免責管轄ポリシーファイルがチェックされます。免責されるアクセス権が関連するアルゴリズムおよび免責機構のエントリを含み、そのエントリがアプリケーションに添付のアクセス権ポリシーファイル内のアクセス権により暗黙的に設定されている場合、および指定された免責機構の実装がいずれかの登録済みプロバイダから利用可能な場合、Cipher の最大キーサイズおよびアルゴリズムパラメータ値は、免責アクセス権エントリにより決定されます。アプリケーションにバンドルされるアクセス権ポリシーファイル内の関連するエントリに、暗黙的に設定された免責アクセス権が存在しない場合、またはいずれかの登録済みプロバイダから利用可能な、指定された免責機構の実装が存在しない場合、デフォルトの標準暗号化アクセス権のみがアプリケーションに付与されます。
MessageDigestオブジェクトの計算まず最初に、以下の例のようにして MessageDigest を生成します。
この呼び出しは、正しく初期化されたメッセージダイジェストオブジェクトを変数MessageDigest sha = MessageDigest.getInstance("SHA-1");shaに代入します。この実装は、National Institute for Standards and Technology の (NIST) FIPS 180-1 ドキュメントの定義に従って、ソースハッシュアルゴリズム (SHA-1) を実装します。標準名とアルゴリズムに関する詳細は、「付録 A」を参照してください。次に、3 つのバイト配列
i1、i2、およびi3があるとします。計算するメッセージダイジェストを持つ合計入力は、この 3 つの配列から形成されます。このダイジェスト (または「ハッシュ」) は、以下の呼び出しを使って計算できます。sha.update(i1); sha.update(i2); sha.update(i3); byte[] hash = sha.digest();以下の一連の呼び出しを使っても同じです。
メッセージダイジェストが計算されると、メッセージダイジェストオブジェクトは自動的にリセットされ、新しいデータをレビューしてそのダイジェストを計算できる状態になります。以前の状態 (たとえばsha.update(i1); sha.update(i2); byte[] hash = sha.digest(i3);update呼び出しで入れたデータ) はすべて失われます。ハッシュ実装によっては、複製 (コピー) を介して中間ハッシュをサポートするものもあります。以下について、別々のハッシュを計算すると仮定します。
i1i1 および i2i1、i2、および i3次のように処理します。
このコードは、SHA-1 実装が複製 (コピー) 可能な場合にだけ機能します。メッセージダイジェストの実装の中には、複製 (コピー) 可能なものもあれば、不可能なものもあります。複製 (コピー) が可能かどうかを判断するには、次のように/* compute the hash for i1 */ sha.update(i1); byte[] i1Hash = sha.clone().digest(); /* compute the hash for i1 and i2 */ sha.update(i2); byte[] i12Hash = sha.clone().digest(); /* compute the hash for i1, i2 and i3 */ sha.update(i3); byte[] i123hash = sha.digest();MessageDigestオブジェクトを複製し、発生する可能性のある例外をキャッチします。メッセージダイジェストが複製 (コピー) 不可能な場合は、別の多少複雑な方法を使います。つまり、複数のダイジェストを生成して中間ダイジェストを計算します。この場合、計算する中間ダイジェストの数をあらかじめ知っておく必要があります。try { // try and clone it /* compute the hash for i1 */ sha.update(i1); byte[] i1Hash = sha.clone().digest(); . . . byte[] i123hash = sha.digest(); } catch (CloneNotSupportedException cnse) { // do something else, such as the code shown below }MessageDigestsha1 = MessageDigest.getInstance("SHA-1");MessageDigestsha12 = MessageDigest.getInstance("SHA-1");MessageDigestsha123 = MessageDigest.getInstance("SHA-1"); byte[] i1Hash = sha1.digest(i1); sha12.update(i1); byte[] i12Hash = sha12.digest(i2); sha123.update(i1); sha123.update(i2); byte[] i123Hash = sha123.digest(i3);鍵のペアの生成
この例では、「DSA」 (デジタル署名アルゴリズム) という名前のアルゴリズムについて、「公開 - 非公開」の鍵のペアを生成します。
userSeedというユーザ作成のシードを使って、1024 ビットモジュラスの鍵を生成します。ここでは、アルゴリズム実装を提供するプロバイダは考慮しません。KeyPairGenerator の生成
最初の手順は、DSA アルゴリズムの鍵を生成するための鍵のペアジェネレータオブジェクトの獲得です。
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");KeyPairGenerator の初期化
次の手順は、鍵のペアジェネレータの初期化です。たいていの場合、アルゴリズム独立型の初期化で十分ですが、アルゴリズム特定型の初期化を使う必要がある場合もあります。アルゴリズム独立型の初期化
すべての鍵ジェネレータは、キーサイズおよび乱数の発生源の概念を共有します。
KeyPairGeneratorクラスのinitializeメソッドには、2 つの型の引数があります。つまり、1024 のキーサイズ、およびuserSeed値を使ってシードした新規のSecureRandomオブジェクトを指定して鍵を生成する場合、以下のコードを使用できます。上のアルゴリズム独立型SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); random.setSeed(userSeed); keyGen.initialize(1024, random);initializeメソッドを呼び出すときは、その他のパラメータは指定しないため、各鍵に関連付けられるアルゴリズム特定型のパラメータがある場合は、パラメータをどうするかは、プロバイダによって異なります。プロバイダは、事前に計算されたパラメータ値を使うことも、新しい値を生成することもできます。アルゴリズム特定型の初期化
アルゴリズム特定型パラメータのセットがすでに存在する状況では (DSA の「コミュニティパラメータ」など)、
AlgorithmParameterSpec引数をとるinitializeメソッドが 2 つあります。鍵のペアのジェネレータが DSA アルゴリズムのジェネレータで、DSA 特定パラメータのセットp、q、およびgがあり、これを使って鍵のペアを生成したいとします。次のコードを実行して鍵のペアのジェネレータを初期化できます。DSAParameterSpecは AlgorithmParameterSpec です。DSAParameterSpec dsaSpec = new DSAParameterSpec(p, q, g); SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); random.setSeed(userSeed); keyGen.initialize(dsaSpec, random);
注: 名前がpのパラメータは、長さがモジュラスの長さ (サイズ) のプライム数です。したがって、モジュラスの長さを指定するために他のメソッドを呼び出す必要はありません。
鍵のペアの生成
最終手順は、鍵のペアの生成です。使用した初期化の型 (アルゴリズム独立型またはアルゴリズム特定型) に関係なく、同じコードを使って鍵のペアを生成します。KeyPair pair = keyGen.generateKeyPair();生成された鍵を使った署名の生成および検証
次の署名の生成および検証の例では、上の鍵のペアの例で生成された鍵のペアを利用しています。
署名の生成
まず最初に署名オブジェクトを生成します。
鍵のペアの例で生成した鍵のペアを使い、非公開鍵を指定してオブジェクトを初期化します。このあとでSignature dsa = Signature.getInstance("SHA1withDSA");dataというバイト配列に署名を付けます。/* Initializing the object with a private key */ PrivateKey priv = pair.getPrivate(); dsa.initSign(priv); /* Update and sign the data */ dsa.update(data); byte[] sig = dsa.sign();署名の検証
署名の検証は簡単です。ここでも、鍵のペアの例で生成した鍵のペアを使います。/* Initializing the object with the public key */ PublicKey pub = pair.getPublic(); dsa.initVerify(pub); /* Update and verify the data */ dsa.update(data); boolean verifies = dsa.verify(sig); System.out.println("signature verifies:" + verifies);鍵仕様および
KeyFactoryを使った署名の生成と検証前述の鍵のペアの例で生成したような公開鍵と非公開鍵のペアを使うよりも、単に DSA 非公開鍵のコンポーネントx(非公開鍵)、p(プライム)、q(サブプライム)、およびg(ベース) を使うとします。さらに、非公開鍵を使って
someDataというバイト配列内のあるデータにデジタル署名を付けたいとします。次の手順を実行します。この手順は、鍵仕様の作成、および鍵ファクトリを使って鍵仕様からPrivateKeyを取得する方法も示しています。initSignにはPrivateKeyが必要です。Alice が署名したデータを使いたいとします。彼女がそのデータを使うため、および署名を検証するためには、彼女に次の 3 つのものを送る必要があります。DSAPrivateKeySpec dsaPrivKeySpec = new DSAPrivateKeySpec(x, p, q, g); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PrivateKey privKey = keyFactory.generatePrivate(dsaPrivKeySpec); Signature sig = Signature.getInstance("SHA1withDSA"); sig.initSign(privKey); sig.update(someData); byte[] signature = sig.sign();
- データ
- 署名
- データの署名に使った非公開鍵に対応する公開鍵
someDataバイトをあるファイルに格納し、signatureバイトを別のファイルに格納し、両方を Alice に送ることができます。公開鍵に関しては、上の署名の例のように、データの署名に使った DSA 非公開鍵に対応する DSA 公開鍵のコンポーネントを持っていると想定します。この場合は、コンポーネントから DSAPublicKeySpec を作成できます。
ただし、鍵バイトをファイルに記述できるように、鍵バイトを抽出する必要があります。このためには、まず、上の例ですでに作成した DSA 鍵ファクトリのDSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec(y, p, q, g);generatePublicメソッドを呼び出します。次に、以下のコードを使って符号化された鍵バイトを抽出します。PublicKey pubKey = keyFactory.generatePublic(dsaPubKeySpec);この時点でバイトをファイルに保存し、データおよび署名を保存したファイルと一緒に Alice に送ることができます。byte[] encKey = pubKey.getEncoded();ここで、Alice がこれらのファイルを受け取り、データファイルのデータバイトを
dataというバイト配列に、署名ファイルの署名バイトをsignatureというバイト配列に、公開鍵ファイルの符号化された公開鍵バイトをencodedPubKeyというバイト配列にコピーしたとします。Alice は、次のコードを実行して署名を検証できます。このコードは、符号化された状態から DSA 公開鍵のインスタンスを生成するために、鍵ファクトリを使う方法も示しています。
initVerifyにはPublicKeyが必要です。X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encodedPubKey); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PublicKey pubKey = keyFactory.generatePublic(pubKeySpec); Signature sig = Signature.getInstance("SHA1withDSA"); sig.initVerify(pubKey); sig.update(data); sig.verify(signature);注: 上のコードでは、initVerifyがPublicKeyを必要とするため、Alice は符号化された鍵ビットからPublicKeyを生成する必要がありました。PublicKeyを取得したら、KeyFactorygetKeySpecメソッドを使って、PublicKeyをDSAPublicKeySpecに変換して、必要な場合にコンポーネントにアクセスすることが可能です。DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec)keyFactory.getKeySpec(pubKey, DSAPublicKeySpec.class)これで Alice は、DSA 公開鍵コンポーネントy、p、q、およびgに、DSAPublicKeySpecクラスの対応する get メソッド (getY、getP、getQ、およびgetG) を使ってアクセスできます。2 つの鍵の同一性の判定
しばしば、2 つの鍵の同一性の判定が必要になることがありますが、デフォルトの
java.lang.Object.equalsメソッドでは、必要な結果が得られない場合があります。プロバイダに対する依存度がもっとも少ない方法は、符号化された鍵を比較する方法です。この方法で適切に比較できない場合 (たとえば、RSAPrivateKeyとRSAPrivateCrtKeyを比較する場合)、各コンポーネントを比較する必要があります。その方法を示すコードを以下に示します。static boolean keysEqual(Key key1, Key key2) { if (key1.equals(key2)) { return true; } if (Arrays.equals(key1.getEncoded(), key2.getEncoded())) { return true; } // More code for different types of keys here. // For example, the following code can check if // an RSAPrivateKey and an RSAPrivateCrtKey are equal: // if ((key1 instanceof RSAPrivateKey) && // (key2 instanceof RSAPrivateKey)) { // if ((key1.getModulus().equals(key2.getModulus())) && // (key1.getPrivateExponent().equals( // key2.getPrivateExponent()))) { // return true; // } // } return false; }Base64−符号化された証明書の読み取り
次の例は、Base64- 符号化された証明書を読み取ります。認証の開始は、次のコードで指定されます。
-----BEGIN CERTIFICATE-----最後は、次の行で終わります。-----END CERTIFICATE-----FileInputStream(markおよびresetをサポートしない) をByteArrayInputStream(markおよびresetをサポートする) に変換し、generateCertificateへの各呼び出しに証明書が 1 つだけ使われて、入力ストリームの読み取られた位置がファイル内の次の証明書に配置されるようにします。
FileInputStream fis = new FileInputStream(filename); BufferedInputStream bis = new BufferedInputStream(fis); CertificateFactory cf = CertificateFactory.getInstance("X.509"); while (bis.available() > 0) { Certificate cert = cf.generateCertificate(bis); System.out.println(cert.toString()); }認証応答の解析
次の例は、ファイル内に保存された PKCS #7 形式の認証応答を解析し、そこから証明書をすべて抽出します。
FileInputStream fis = new FileInputStream(filename); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Collection c = cf.generateCertificates(fis); Iterator i = c.iterator(); while (i.hasNext()) { Certificate cert = (Certificate)i.next(); System.out.println(cert); }このセクションでは、Java 2 SDK, v 5.0 の JCE API の主な機能の使用方法について説明します。この API を実行する完全なサンプルプログラムは、このドキュメントの「付録 F」に掲載されています。
暗号化の使用
このセクションでは、鍵の生成、Cipher オブジェクトの作成と初期化、およびファイルの暗号化と暗号解読という一連の処理について説明します。この例全体で、データ暗号化規格 (DES) を使用します。
鍵の生成
DES を作成するには、DES 用の KeyGenerator をインスタンス化する必要があります。特定の DES 鍵生成実装について考慮する必要はないため、プロバイダは指定しません。KeyGenerator を初期化しないため、DES 鍵の作成にはシステム提供の乱数発生源が使用されます。
KeyGenerator keygen = KeyGenerator.getInstance("DES");
SecretKey desKey = keygen.generateKey();鍵を生成したあと、同じ KeyGenerator を使用して他の鍵を再度作成できます。
Cipher の作成
次のステップは、Cipher インスタンスの作成です。これには、Cipher クラスのいずれかの
getInstanceファクトリメソッドを使用します。次のコンポーネントを含む必須の変換名を、スラッシュ (/) で区切って指定する必要があります。
- アルゴリズム名
- モード (オプション)
- パディング方式 (オプション)
この例では、Electronic Codebook モードおよび PKCS #5 パディング方式で DES (データ暗号化規格) 暗号を作成します。特定の必須変換の実装について考慮する必要はないため、プロバイダは指定しません。
DES の標準アルゴリズム名は「DES」、Electronic Codebook モードの標準名は「ECB」、PKCS #5 パディング方式の標準名は「PKCS5Padding」です。
Cipher desCipher;
// Create the cipher
desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");上で生成された
desKeyを使用して、Cipher オブジェクトを暗号化用に初期化します。// Initialize the cipher for encryption
desCipher.init(Cipher.ENCRYPT_MODE, desKey);
// Our cleartext
byte[] cleartext = "This is just an example".getBytes();
// Encrypt the cleartext
byte[] ciphertext = desCipher.doFinal(cleartext);
// Initialize the same cipher for decryption
desCipher.init(Cipher.DECRYPT_MODE, desKey);
// Decrypt the ciphertext
byte[] cleartext1 = desCipher.doFinal(ciphertext);
cleartextとcleartext1は、同一です。パスワードベース暗号化の使用
この例では、ユーザにパスワードを要求し、暗号化鍵をそのパスワードから導き出します。
java.lang.String型のオブジェクトにパスワードを収集および格納するのは、適切と考えられます。ただし、注意すべき点があります。それは、String型のオブジェクトは不変であるということです。このため、使用後にStringの内容を変更 (上書き) またはゼロにするようなメソッドは存在しません。この機能のために、Stringオブジェクトは、ユーザパスワードなどセキュリティ上重要な情報の格納には適しません。セキュリティ関連の情報は、常に char 型の配列に収集および格納するようにしてください。この理由で、
javax.crypto.spec.PBEKeySpecクラスは、パスワードを char 型の配列として受け取り、返します。次のメソッド例に、ユーザパスワードを char 型の配列として収集する方法を示します。
/**
* Reads user password from given input stream.
*/
public char[] readPasswd(InputStream in) throws IOException {
char[] lineBuffer;
char[] buf;
int i;
buf = lineBuffer = new char[128];
int room = buf.length;
int offset = 0;
int c;
loop:while (true) {
switch (c = in.read()) {
case -1:
case '\n':
break loop;
case '\r':
int c2 = in.read();
if ((c2 != '\n') && (c2 != -1)) {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
} else
break loop;
default:
if (--room < 0) {
buf = new char[offset + 128];
room = buf.length - offset - 1;
System.arraycopy(lineBuffer, 0, buf, 0, offset);
Arrays.fill(lineBuffer, ' ');
lineBuffer = buf;
}
buf[offset++] = (char) c;
break;
}
}
if (offset == 0) {
return null;
}
char[] ret = new char[offset];
System.arraycopy(buf, 0, ret, 0, offset);
Arrays.fill(buf, ' ');
return ret;
}PKCS #5 で定義された パスワードベースの暗号化 (PBE) を使用するには、salt と繰り返し処理の回数を指定する必要があります。暗号解読時にも、暗号化時と同じ salt および繰り返し処理の回数を使用する必要があります。
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = {
(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
(byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};
// Iteration count
int count = 20;
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
// Prompt user for encryption password.
// Collect user password as char array (using the
// "readPasswd" method from above), and convert
// it into a SecretKey object, using a PBE key
// factory.
System.out.print("Enter encryption password:");
System.out.flush();
pbeKeySpec = new PBEKeySpec(readPasswd(System.in));
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Our cleartext
byte[] cleartext = "This is another example".getBytes();
// Encrypt the cleartext
byte[] ciphertext = pbeCipher.doFinal(cleartext);鍵協定の使用
2 つおよび 3 つのパーティ間で Diffie-Hellman 鍵交換を実行するサンプルプログラムに関しては、「付録 F」を参照してください。
Java 2 SDK Security API は、さまざまなアルゴリズム、証明書、およびキーストアのタイプの標準名を必要とし、これらを使用します。ここに記載の仕様は、標準名として以下の名前を確立するものです。
場合によっては、複数のプロバイダの実装にわたって名前の一貫性を維持できるように、明示的に記載されていない名前の命名規約が提案されることがあります。それらの提案では、特定のメッセージダイジェスト、暗号化アルゴリズム、その他の名前で置き換えるためのプレースホルダとして、山括弧で囲まれた項目 (<digest>、<encryption> など) が使用されます。
この付録には、さまざまなセキュリティのサブ領域に関連する標準名の対応一覧を記載しています。
注: アルゴリズム名の大文字と小文字は区別されません。
アルゴリズムの仕様については、付録 B を参照してください。
メッセージダイジェストアルゴリズム
この項のアルゴリズム名は、
MessageDigestのインスタンスの生成時に指定できます。MD2: RFC 1319 で定義されている MD2 メッセージダイジェストアルゴリズム
MD5: RFC 1321 で定義されている MD5 メッセージダイジェストアルゴリズム
SHA-1: セキュアハッシュ標準 NIST FIPS 180-1 で定義されているセキュアハッシュアルゴリズム
SHA-256、SHA-384、および SHA-512: 新しいハッシュアルゴリズム。これらは、draft Federal Information Processing Standard 180-2, Secure Hash Standard (SHS) に記載されています。SHA-256 は、衝突攻撃に備えて 128 ビットのセキュリティを提供するための 256 ビットハッシュ機能であり、SHA-512 は、256 ビットのセキュリティを提供するための 512 ビットハッシュ機能です。SHA-512 の出力を切り捨てることによって、384 ビットのハッシュを得ることができます。
鍵およびパラメータのアルゴリズム
この項のアルゴリズム名は、
KeyPairGenerator、KeyFactory、AlgorithmParameterGenerator、およびAlgorithmParametersのインスタンスの生成時に指定できます。DSA: FIPS PUB 186 で定義されているデジタル署名アルゴリズム
RSA: PKCS #1 で定義されている RSA 暗号化アルゴリズム
デジタル署名アルゴリズム
この項のアルゴリズム名は、
Signatureのインスタンスの生成時に指定できます。ECDSA (Elliptic Curve Digital Signature Algorithm): ECC Cipher Suites for TLS (2004 年 1 月 ドラフト) に記載されている認証機構。
MD2withRSA: PKCS #1 に定義されている RSA 暗号を使った MD2 署名アルゴリズム。MD2 ダイジェストアルゴリズムおよび RSA を使って RSA デジタル署名を作成および検証します。
MD5withRSA: PKCS #1 に定義されている RSA 暗号を使った MD5 署名アルゴリズム。MD5 ダイジェストアルゴリズムおよび RSA を使って RSA デジタル署名を作成および検証します。
NONEwithDSA: FIPS PUB 186 に定義されている署名アルゴリズム。署名されるダイレクト raw データを受け取り、DSA を使って DSA デジタル署名を作成および検証します。データの長さはちょうど 20 バイトである必要があります。このアルゴリズムは、RawDSA とも呼ばれています。
SHA1withDSA: FIPS PUB 186 に定義されている SHA-1 を使った DSA 署名アルゴリズム。SHA-1 ダイジェストアルゴリズムおよび DSA を使って DSA デジタル署名を作成および検証します。
SHA1withRSA: OSI Interoperability Workshop に定義されている SHA-1 および RSA 暗号化アルゴリズムを使った署名アルゴリズム。PKCS #1 で説明されているパディング規則を使います。
<digest>with<encryption>: この形式を使用して、特定のメッセージ ダイジェスト (MD2、MD5 など) とアルゴリズム (RSA、DSA など) を使用する署名アルゴリズムの名前を指定します。この節で紹介した明示的に定義されている標準名 (MD2withRSA など) も同じ形式で指定されています。PKCS #1 v 2.0 に定義された新しい署名スキーマの場合は、<digest>with<encryption> の形式では不十分なため、<digest>with<encryption>and<mgf> の形式を使って、名前を指定できます。<mgf> は、MGF1 などのマスク生成機能に置き換える必要があります。例: MD5withRSAandMGF1
乱数生成 (RNG) アルゴリズム
この項のアルゴリズム名は、
SecureRandomのインスタンスの生成時に指定できます。SHA1PRNG: Sun プロバイダが提供する擬似乱数生成 (PRNG) アルゴリズム。この実装は、IEEE P1363 標準の付録 G.7「Expansion of source bits」に準拠しており、PRNG の基盤として SHA-1 を使います。各操作につき値が 1 増加する 64 ビットカウンタを使って鎖状につながった真にランダムなシード値から、SHA-1 ハッシュを計算します。160 ビットの SHA‐1 出力のうち、64 ビットだけが使用されます。
証明書のタイプ
この項のアルゴリズム名は、
CertificateFactoryのインスタンスの生成時に指定できます。X.509:X.509 に定義されている証明書のタイプ
キーストアのタイプ
この項のアルゴリズム名は、
KeyStoreのインスタンスの生成時に指定できます。JKS: Sun プロバイダが提供するキーストア実装の名前
PKCS12: PKCS #12 に定義されている、個人のアイデンティティ情報のための転送構文
サービス属性
暗号化サービスは、常に特定のアルゴリズムまたはタイプに関連付けられています。たとえば、デジタル署名サービスは常に特定のアルゴリズム (DSA など) に、CertificateFactoryサービスは常に特定の証明書タイプ (X.509 など) にそれぞれ関連付けられています。ここで示されている属性は、暗号化サービス用のものです。サービス属性は、プロバイダを選択するためのフィルタとして使用できます。
属性名および属性値は両方とも大文字と小文字を区別しません。
KeySize: プロバイダが暗号化サービスのためにサポートしている最大のキーサイズ
ImplementedIn: 暗号化サービスの実装がソフトウェアとハードウェアのどちらで行われているか。この属性の値は、「software」と「hardware」のどちらかになります。
JCE API では、アルゴリズム、アルゴリズムモード、およびパディング方式の標準名のセットが必要とされ、使用されます。ここに記載の仕様は、標準名として以下の名前を確立するものです。また、「JavaTM 暗号化アーキテクチャ API の仕様およびリファレンス」の「付録 A」で定義された標準名のリストを補足する内容となっています。アルゴリズム名の大文字と小文字が区別されることに留意してください。
場合によっては、複数のプロバイダの実装にわたって名前の一貫性を維持できるように、明示的に記載されていない名前の命名規約が提案されることがあります。それらの提案では、特定のメッセージダイジェスト、暗号化アルゴリズム、その他の名前で置き換えるためのプレースホルダとして、山括弧で囲まれた項目 (<digest>、<encryption> など) が使用されます。
暗号
アルゴリズム
Cipherのインスタンスを要求する場合、次の名前を変換内の algorithm コンポーネントとして指定できます。
- AES: Advanced Encryption Standard として、NIST によって FIPS ドラフトに指定された。Joan Daemen、Vincent Rijmen 両氏による Rijndael アルゴリズムに基づいた 128 ビットのブロック暗号であり、128 ビット、192 ビット、256 ビットの鍵をサポートする
- ARCFOUR/RC4: Ron Rivest が開発したストリーム暗号。詳細については、K. Kaukonen、R. Thayer 著「A Stream Cipher Encryption Algorithm 'Arcfour'」、Internet Draft (expired)、draft-kaukonen-cipher-arcfour-03.txt を参照
- Blowfish: Bruce Schneier 氏の設計によるブロック暗号
- DES: データ暗号化規格 (FIPS PUB 46-2 で定義)
- DESede: トリプル DES 暗号化 (DES-EDE)
- ECIES (Elliptic Curve Integrated Encryption Scheme)
- PBEWith<digest>And<encryption> または PBEWith<prf>And<encryption>: パスワードベースの暗号アルゴリズム (PKCS #5) で、指定されたメッセージダイジェスト (digest) または擬似暗号関数 (prf)、暗号アルゴリズム (encryption) を使用する。例
- PBEWithMD5AndDES: 1993 年 11 月、RSA Laboratories の「PKCS #5: Password-Based Encryption Standard」バージョン 1.5 に定義されたパスワードベースの暗号化アルゴリズム。このアルゴリズムでは、CBC は暗号モード、PKCS5Padding はパディング方式とされている。他の暗号モードやパディング方式で使用することはできない
- PBEWithHmacSHA1AndDESede: 1999 年 3 月、RSA Laboratories の「PKCS #5: Password-Based Encryption Standard」バージョン 2.0 に定義されたパスワードベースの暗号化アルゴリズム
- RC2、RC4、および RC5: RSA Data Security, Inc の Ron Rivest により開発された可変キーサイズ暗号化アルゴリズム
- RSA: PKCS #1 で定義されている RSA 暗号化アルゴリズム
モード
Cipherのインスタンスを要求する場合、次の名前を変換内の mode コンポーネントとして指定できます。
- NONE: モードなし
- CBC: FIPS PUB 81 で定義された Cipher Block Chaining Mode
- CFB: FIPS PUB 81 で定義された Cipher Feedback Mode
- ECB: 米国商務省 National Institute of Standards and Technology (NIST) の Federal Information Processing Standard (FIPS) PUB 81「DES Modes of Operation」で定義された Electronic Codebook Mode (1980 年 12 月)
- OFB: FIPS PUB 81 で定義された Output Feedback Mode
- PCBC: Kerberos バージョン 4 で定義された Propagating Cipher Block Chaining
パディング
Cipherのインスタンスを要求する場合、次の名前を変換内の padding コンポーネントとして指定できます。
- ISO10126Padding: このブロック暗号用パディングは、W3C の「XML Encryption Syntax and Processing」ドキュメントの 5.2 Block Encryption Algorithms に記載されている
- NoPadding: パディングなし
- OAEPWith<digest>And<mgf>Padding: PKCS #1 に定義されている Optimal Asymmetric Encryption Padding スキーマ。<digest> はメッセージダイジェスト、<mgf> はマスク生成関数で置き換える(例: AEPWithMD5AndMGF1Padding)
- PKCS5Padding: 「PKCS #5: Password-Based Encryption Standard」バージョン 1.5 (RSA Laboratories、1993 年 11 月) で規定されたパディング方式
- SSL3Padding: SSL Protocol バージョン 3.0 のセクション 5.2.3.2 (CBC ブロック暗号) で規定されたパディング方式
block-ciphered struct {
opaque content[SSLCompressed.length];
opaque MAC[CipherSpec.hash_size];
uint8 padding[GenericBlockCipher.padding_length];
uint8 padding_length;
} GenericBlockCipher;GenericBlockCipher のインスタンスのサイズは、ブロック暗号のブロック長の倍数でなければなりません。
パディングは、パディング長 (常に存在) に影響を受けます。次の式が当てはまる場合を考えましょう。
sizeof(content) + sizeof(MAC) % block_length = 0,この場合、padding_lengthが存在するため、パディング長を (block_length - 1) バイトにする必要があります。このため、パディング方式は PKCS5Padding に類似した (まったく同一ではない) ものになります。パディング長は、パディング内で符号化され、1 〜 block_length の範囲の値になります。SSL スキーマでは、パディングのサイズは、常に存在する
padding_length内で符号化されるため、0 〜 block_length-1 の範囲の値になります。「SunJCE」プロバイダは、このパディング機構をサポートしない点に留意してください。
KeyAgreement
KeyAgreementのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- DiffieHellman: 「PKCS #3: Diffie-Hellman Key-Agreement Standard」バージョン 1.4 (RSA Laboratories、1993 年 11 月) で定義された Diffie-Hellman 鍵協定
- ECDH (Elliptic Curve Diffie-Hellman): RFC 3278、「Use of Elliptic Curve Cryptography (ECC) Algorithms in Cryptographic Message Syntax (CMS)」に記載
- ECMQV (Elliptic Curve Menezes-Qu-Vanstone): ECC Cipher Suites for TLS (2004 年 1 月 ドラフト) に記載
KeyGenerator
KeyGeneratorのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- AES
- ARCFOUR/RC4
- Blowfish
- DES
- DESede
- HmacMD5
- HmacSHA1
- HmacSHA256
- HmacSHA384
- HmacSHA512
- RC2
KeyPairGenerator
KeyPairGeneratorのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- DiffieHellman
SecretKeyFactory
SecretKeyFactoryのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- DES
- DESede
- PBEWith<digest>And<encryption> または PBEWith<prf>And<encryption>: パスワードベースの暗号化 PKCS #5 で使用される秘密鍵ファクトリ。<digest> はメッセージダイジェスト、<prf> は擬似ランダム関数、<encryption> は暗号化アルゴリズム。たとえば、PBEWithMD5AndDES (PKCS #5, v 1.5)、PBEWithHmacSHA1AndDESede (PKCS #5, v 2.0) などがある。注: これらは各パスワード文字の下位 8 ビットのみを使用する
KeyFactory
KeyFactoryのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- DiffieHellman
AlgorithmParameterGenerator
AlgorithmParameterGeneratorのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- DiffieHellman
AlgorithmParameters
AlgorithmParametersのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- AES
- Blowfish
- DES
- DESede
- DiffieHellman
- OAEP
- PBE
- PBEWith<digest>And<encryption>
- RC2
MAC
Macのインスタンスを要求する際、次のアルゴリズム名を指定できます。
- HmacMD5: RFC 2104「HMAC: Keyed-Hashing for Message Authentication」 (1997 年 2 月) で定義された HMAC-MD5 キーハッシュアルゴリズム
- HmacSHA1: RFC 2104「HMAC: Keyed-Hashing for Message Authentication」 (1997 年 2 月) で定義された HMAC-SHA1 キーハッシュアルゴリズム
- HmacSHA256: RFC 2104「HMAC: Keyed-Hashing for Message Authentication」 (1997 年 2 月) で定義された、
SHA-256をメッセージダイジェストアルゴリズムとする HmacSHA256 アルゴリズム- HmacSHA384: RFC 2104「HMAC: Keyed-Hashing for Message Authentication」 (1997 年 2 月) で定義された、
SHA-384をメッセージダイジェストアルゴリズムとする HmacSHA384 アルゴリズム- HmacSHA512: RFC 2104「HMAC: Keyed-Hashing for Message Authentication」 (1997 年 2 月) で定義された、
SHA-512をメッセージダイジェストアルゴリズムとする HmacSHA512 アルゴリズム- PBEWith<mac>: パスワードベースのメッセージ認証規格、PKCS #5 バージョン 2.0 で使用される MAC。<mac> はメッセージ認証コードのアルゴリズム名。例: PBEWithHmacSHA1
キーストアのタイプ
KeyStoreのインスタンスを要求する際、次の型を指定できます。
- JCEKS: 「SunJCE」により実装された独自のキーストア型
免責機構
暗号化制限を「免責された」と見なされるアプリケーションに付属するアクセス権ポリシーファイル内で、次の免責機構名を指定できます。
- KeyEscrow: バックアップ暗号解読機能付き暗号化システム。このシステムを利用すると、特定条件下で、承認された人物 (ユーザ、組織役員、政府職員) が、特別なデータ復元鍵を保持する信頼できる 1 つ以上のパーティの提供する情報を利用して、暗号解読を実行できる
- KeyRecovery: 暗号化データのロックに使用する秘密鍵を取得するメソッド。これは、災害発生時に、企業独自の暗号化情報への復旧アクセスを実行する手段として使用できる
- KeyWeakening: 鍵の一部をエスクローまたは復元可能なメソッド
SunJCE プロバイダは、次のデフォルトキーサイズを使用します。
- KeyGenerator
- DES: 56 ビット
- トリプル DES: 112 ビット
- Blowfish: 56 ビット
- HmacMD5: 64 バイト
- HmacSHA1: 64 バイト
- KeyPairGenerator
- Diffie-Hellman: 1024 ビット
- AlgorithmParameterGenerator
- Diffie-Hellman: 1024 ビット
SunJCE プロバイダでは、次のクラスの初期化メソッドに渡すキーサイズに制限が課されます。
- KeyGenerator
制限 (アルゴリズム別):
- DES: キーサイズを
56にする必要がある- トリプル DES: キーサイズを
112または168にする必要がある注: キーサイズが
112の場合には 2 つの中間鍵を保持するトリプル DES 鍵が、168の場合には 3 つの中間鍵を保持するトリプル DES 鍵が、それぞれ生成されます。- Blowfish: キーサイズを、
8の倍数 (32以上448以下) にする必要がある- KeyPairGenerator
制限 (アルゴリズム別):
- Diffie-Hellman: キーサイズを、
64の倍数 (512以上1024以下) にする必要がある- AlgorithmParameterGenerator
制限 (アルゴリズム別):
- Diffie-Hellman: キーサイズを、
64の倍数 (512以上1024以下) にする必要がある
JCE の管轄ポリシーファイルは、J2SE 形式のポリシーファイル (対応するアクセス権を指定する文を含む) で表されます。「デフォルトの Policy の実装とポリシーファイルの構文」に説明されているように、J2SE ポリシーファイルでは、指定されたコードソースのコードに付与するアクセス権を指定します。アクセス権は、システムリソースへのアクセスを表します。JCE の場合、「リソース」は暗号化アルゴリズムです。また、暗号化制限はすべてのコードに適用されるため、コードソースを指定する必要はありません。
管轄ポリシーファイルは、1 つ以上の「アクセス権エントリ」を含む、非常に基本的な「付与エントリ」で構成されます。
grant {
<permission entries>;
};以下に、管轄ポリシーファイルのアクセス権エントリの書式を示します。
permission <crypto permission class name>[ <alg_name>
[[, <exemption mechanism name>][, <maxKeySize>
[, <AlgorithmParameterSpec class name>,
<parameters for constructing an
AlgorithmParameterSpec object>]]]];以下に、「Blowfish」アルゴリズムを 64 ビットの最大キーサイズに制限する、管轄ポリシーファイルのサンプルを示します。
grant {
permission javax.crypto.CryptoPermission "Blowfish", 64;
. . .;
};アクセス権エントリは、
permissionで始まります。上記のテンプレート内の<crypto permission class name>には、javax.crypto.CryptoPermissionなどの具体的なアクセス権クラス名を指定します。暗号化アクセス権クラスは、特定の環境下で特定のキーサイズを使用するアプリケーション/アプレットの機能に対応します。暗号化アクセス権クラスには、CryptoPermissionおよびCryptoAllPermissionの 2 つが存在します。特別なCryptoAllPermissionクラスは、暗号化関連のアクセス権すべてを表します。つまり、暗号化関連の制限はないことを示します。<alg_name> を指定する場合、"DES" や "RSA" など暗号化アルゴリズムの標準名を表す文字列 (「付録 A」を参照) を引用符で囲んで指定します。
<免責機構名> を指定する場合、免責機構を指す文字列を引用符で囲んで指定します。免責機構を実施すると、暗号化制限が緩和されます。使用可能な免責機構名には、「KeyRecovery」、「KeyEscrow」、および「KeyWeakening」が含まれます。
<maxKeySize> には、指定したアルゴリズムに許可する最大鍵サイズ (ビット) を示す整数値を指定します。
アルゴリズムによっては、キーサイズでアルゴリズムの強度を指定するだけでは不十分な場合があります。たとえば、"RC5" アルゴリズムの場合には、ラウンド数も考慮する必要があります。アルゴリズムの強度をキーサイズだけで表現するのでは不十分な場合、アクセス権エントリで AlgorithmParameterSpec クラス名 (
javax.crypto.spec.RC5ParameterSpecなど)、および指定された AlgorithmParameterSpec オブジェクトの構築用パラメータリストも指定する必要があります。アクセス権エントリの各項目は、指定された順序で記述する必要があります。各エントリはセミコロンで終わります。
識別子 (
grant、permission) では大文字と小文字は区別されませんが、<crypto permission class name>、および値として引き渡される文字列では大文字と小文字が区別されます。注: 「*」は、すべてのアクセス権エントリオプションでワイルドカードとして使用できます。たとえば、<alg_name> に「*」を指定すると、「すべてのアルゴリズム」という意味になります。
輸入管理制限があるため、Java 2 SDK, v 5.0 に同梱された管轄ポリシーファイルは「強固」ですが、暗号化の使用には制限があります。以下に、この「強力な」バージョンの管轄ポリシーファイルで許可される最大キーサイズを示します。
アルゴリズム
最大キーサイズ
DES
64
DESede
*
RC2
128
RC4
128
RC5
128
RSA
2048
* (その他すべて)
128
この付録では、付録 A で定義したアルゴリズムの中のいくつかを詳細に指定しています。掲載されているアルゴリズムの実装を提供するプロバイダは、この付録の仕様に従わなければなりません。
注: このドキュメントの最新バージョンは、公開 Web サイト http://java.sun.com/j2se/1.5.0/docs/guide/security/index.html から入手できます。
ここに記載のない新しいアルゴリズムを追加するには、まず最初にプロバイダパッケージの供給先に問い合わせて、該当アルゴリズムが追加済みでないかどうかを確認します。すでに追加されている場合は、可能であれば開示されている定義を使います。まだ追加されていない場合は、アルゴリズムの仕様を添えて、この付録 B に記載のテンプレートに類似した使用可能なテンプレートを作成します。
仕様テンプレート
次の表に、アルゴリズムの仕様のフィールドを示します。
フィールド 説明 名前 アルゴリズムの認識名。これは、既存のアルゴリズムオブジェクト名を判別するために、(アルゴリズムの要求時に) getInstanceメソッドに渡される名前で、getAlgorithmメソッドによって返される。これらのメソッドは、関連エンジンクラス、Signature、MessageDigest、KeyPairGenerator、およびAlgorithmParameterGenerator内にある型 アルゴリズムの型。 Signature、MessageDigest、KeyPairGenerator、およびParameterGenerator内にある説明 アルゴリズムに関する一般注意。アルゴリズムにより実装される標準、実用向き特許などを含む KeyPairアルゴリズム (オプション指定)このアルゴリズムの KeyPair アルゴリズムを示す キーサイズ (オプション指定) 鍵アルゴリズムまたは鍵生成アルゴリズムの場合は、正しいキーサイズを示す サイズ (オプション指定)
アルゴリズムパラメータ生成アルゴリズムの場合は、アルゴリズムパラメータ生成の正しい「サイズ」を示す パラメータのデフォルト値 (オプション指定)
鍵生成アルゴリズムの場合は、デフォルトのパラメータ値を示す
Signatureフォーマット (オプション指定)Signatureアルゴリズムの場合は、署名のフォーマット (検証メソッドの入力と署名メソッドの出力) を示すアルゴリズムの仕様
SHA-1 メッセージダイジェストアルゴリズム
名前 SHA-1 型 MessageDigest説明 NIST の FIPS 180-1 で定義されているメッセージダイジェストアルゴリズム。このアルゴリズムの出力は 160 ビットのダイジェスト MD2 メッセージダイジェストアルゴリズム
名前 MD2 型 MessageDigest説明 RFC 1319 で定義されているメッセージダイジェストアルゴリズム。このアルゴリズムの出力は 128 ビット (16 バイト) のダイジェスト MD5 メッセージダイジェストアルゴリズム
名前 MD5 型 MessageDigest説明 RFC 1321 で定義されているメッセージダイジェストアルゴリズム。このアルゴリズムの出力は 128 ビット (16 バイト) のダイジェスト デジタル署名アルゴリズム
名前 SHA1withDSA 型 Signature説明 NIST FIPS 186 に記述の署名アルゴリズム。DSA は SHA-1 メッセージダイジェストアルゴリズムを使用する KeyPairアルゴリズムDSA 署名フォーマット ASN.1 の 2 つの INTEGER 値、 rおよびsのシーケンス (この順序)。SEQUENCE ::= { r INTEGER, s INTEGER }MD2、MD5 または SHA-1 を使用する RSA ベースの署名アルゴリズム
名前 MD2withRSA、MD5withRSA、および SHA1withRSA 型 Signature説明 それぞれに MD2、MD5、および SHA‐1 メッセージアルゴリズムを RSA 暗号化とともに使う署名アルゴリズム KeyPairアルゴリズム RSA署名フォーマット RSA Laboratory の「公開鍵暗号化標準ノート #1」で定義の DER 符号化 PKCS #1 ブロック。暗号化データは署名付きデータのダイジェスト DSA KeyPair 生成アルゴリズム
名前 DSA 型 KeyPairGenerator説明 DSA 対応 NIST FIPS 186 に記載の鍵のペア生成アルゴリズム キーサイズ 係数 pの長さ (ビット単位)。512 から 1024 の範囲で、64 の倍数である必要がある。デフォルトのキーサイズは 1024パラメータのデフォルト値 以下のデフォルトのパラメータ値は、512、768、および 1024 ビットのキーサイズ用に使用する
512 ビットの鍵パラメータ
SEED = b869c82b 35d70e1b 1ff91b28 e37a62ec dc34409b counter = 123 p = fca682ce 8e12caba 26efccf7 110e526d b078b05e decbcd1e b4a208f3 ae1617ae 01f35b91 a47e6df6 3413c5e1 2ed0899b cd132acd 50d99151 bdc43ee7 37592e17 q = 962eddcc 369cba8e bb260ee6 b6a126d9 346e38c5 g = 678471b2 7a9cf44e e91a49c5 147db1a9 aaf244f0 5a434d64 86931d2d 14271b9e 35030b71 fd73da17 9069b32e 2935630e 1c206235 4d0da20a 6c416e50 be794ca4768 ビットの鍵パラメータ
SEED = 77d0f8c4 dad15eb8 c4f2f8d6 726cefd9 6d5bb399 counter = 263 p = e9e64259 9d355f37 c97ffd35 67120b8e 25c9cd43 e927b3a9 670fbec5 d8901419 22d2c3b3 ad248009 3799869d 1e846aab 49fab0ad 26d2ce6a 22219d47 0bce7d77 7d4a21fb e9c270b5 7f607002 f3cef839 3694cf45 ee3688c1 1a8c56ab 127a3daf q = 9cdbd84c 9f1ac2f3 8d0f80f4 2ab952e7 338bf511 g = 30470ad5 a005fb14 ce2d9dcd 87e38bc7 d1b1c5fa cbaecbe9 5f190aa7 a31d23c4 dbbcbe06 17454440 1a5b2c02 0965d8c2 bd2171d3 66844577 1f74ba08 4d2029d8 3c1c1585 47f3a9f1 a2715be2 3d51ae4d 3e5a1f6a 7064f316 933a346d 3f5292521024 ビットの鍵パラメータ
SEED = 8d515589 4229d5e6 89ee01e6 018a237e 2cae64cd counter = 92 p = fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80 b6512669 455d4022 51fb593d 8d58fabf c5f5ba30 f6cb9b55 6cd7813b 801d346f f26660b7 6b9950a5 a49f9fe8 047b1022 c24fbba9 d7feb7c6 1bf83b57 e7c6a8a6 150f04fb 83f6d3c5 1ec30235 54135a16 9132f675 f3ae2b61 d72aeff2 2203199d d14801c7 q = 9760508f 15230bcc b292b982 a2eb840b f0581cf5 g = f7e1a085 d69b3dde cbbcab5c 36b857b9 7994afbb fa3aea82 f9574c0b 3d078267 5159578e bad4594f e6710710 8180b449 167123e8 4c281613 b7cf0932 8cc8a6e1 3c167a8b 547c8d28 e0a3ae1e 2bb3a675 916ea37f 0bfa2135 62f1fb62 7a01243b cca4f1be a8519089 a883dfe1 5ae59f06 928b665e 807b5525 64014c3b fecf492aRSA KeyPair 生成アルゴリズム
名前 RSA 型 KeyPairGenerator説明 PKCS #1 に記載の鍵のペア生成アルゴリズム 強度 512 以上で 8 の倍数の任意の整数 DSA パラメータ生成アルゴリズム
名前 DSA 型 ParameterGenerator説明 NIST FIPS 186 for DSA に記載のパラメータ生成アルゴリズム 強度 係数 pの長さ (ビット単位)。512 から 1024 の範囲で、64 の倍数である必要がある。デフォルトのキーサイズは 1024