JavaTM 暗号化拡張機能 (JCE)

リファレンスガイド

JavaTM 2 SDK, Standard Edition, v 1.4


はじめに

Java 2 SDK, v 1.4 における JCE の新機能

暗号化の概要
暗号化および暗号解読
パスワードベース暗号化
暗号
鍵協定
メッセージ認証コード

コアクラス
Cipher クラス
Cipher Stream クラス
CipherInputStream クラス
CipherOutputStream クラス
KeyGenerator クラス
SecretKeyFactory クラス
SealedObject クラス
KeyAgreement クラス
Mac クラス

アプリケーションの暗号化制限の「免責」を取得する方法

Java 2 SDK, v 1.4 対応 JCE プロバイダのインストール

JCE キーストア

コード例
暗号化の使用
パスワードベース暗号化の使用
鍵協定の使用


付録 A: 標準名

付録 B: SunJCE のデフォルトキーサイズ

付録 C: SunJCE のキーサイズ制限

付録 D: 管轄ポリシーファイルの形式

付録 E: 「強力」な管轄ポリシーファイルにより許可される最大キーサイズ

付録 F:サンプルプログラム
2 つのパーティ間の Diffie-Hellman 鍵交換
3 つのパーティ間の Diffie-Hellman 鍵交換
Blowfish の例
HMAC-MD5 の例

はじめに

このドキュメントは、「JavaTM 暗号化アーキテクチャ (JCA) 仕様およびリファレンス」と共に使用してください。このドキュメントに存在しない章への言及がなされている場合、「JCA 仕様」の章を参照してください。

JavaTM 暗号化拡張機能 (JCE) は、暗号化、鍵生成と鍵協定、およびメッセージ認証コード (MAC) アルゴリズム用のフレームワークおよび実装を提供します。暗号化サポートには、対称、非対称、ブロック、およびストリーム暗号が含まれます。このソフトウェアは、セキュリティ保護されたストリームおよびシールされたオブジェクトもサポートします。

JavaTM 2 SDK, Standard Edition (Java 2 SDK) バージョン 1.2.x および 1.3.x では、JCE はオプションパッケージ (拡張機能) でした。Java 2 SDK, v 1.4 には JCE が統合されています。

JCE は、実装非依存および可能な場合にはアルゴリズム非依存など、JCA の他の場所と同じ設計方針に基づいています。使用する「プロバイダ」アーキテクチャは、同一です。信頼できるエンティティにより署名されたプロバイダは、JCE フレームワークへのプラグインが可能です。また、新規アルゴリズムをシームレスに追加できます。

JCE API には、以下が含まれます。

Java 2 SDK, v 1.4 リリースには、SunJCE という名前の標準 JCE プロバイダがあらかじめインストールおよび登録されています。SunJCE は、次の暗号化サービスを提供します。

用語に関する注記

Java 2 SDK, v 1.4 の JCE には、次の 2 つのソフトウェアコンポーネントが含まれます。

このドキュメントでは、「JCE」という語は、Java 2 SDK, v 1.4 の JCE フレームワークを指して使われています。 Java 2 SDK, v 1.4 とともに提供される JCE プロバイダに言及する場合、常に「SunJCE」プロバイダのことを明示的に指しています。

Java 2 SDK, v 1.4 における JCE の新機能

以下に、JCE 1.2.1 の JCE と J2SDK, v 1.4 の JCE の相違点を示します。

Java 2 SDK に含まれる新しい JCE

Java JCE は、JavaTM 2 SDK, Standard Edition (Java 2 SDK) バージョン 1.2.x および 1.3.x では、オプションのパッケージでしたが、現在は Java 2 SDK, v 1.4 に統合されています。また SunJCE プロバイダは、Java 2 SDK, v 1.4 に含まれる セキュリティプロパティファイル java.security にも含まれ、自動的に登録されます。

強力な暗号化機能をデフォルトで装備し、無制限に利用可能

輸入管理制限があるため、Java 2 SDK, v 1.4 に同梱された管轄ポリシーファイルは「強固」ですが、暗号化の使用には制限があります。適格国 (大半の国が該当) の在住者は、暗号化機能に制限のない「強度無制限」のバージョンを利用できます。 このバージョンをダウンロードして、Java 2 SDK, v 1.4 に含まれる暗号化の強力なバージョンと置き換えることができます。無制限のバージョンのダウンロード方法の詳細は、以下を参照してください。

http://java.sun.com/products/jce/index-14.html

管轄ポリシーファイルは、次の場所に移されました。

<java-home>¥lib¥security         [Win32]
<java-home>/lib/security         [Solaris]
ここで、<java-home> は、ランタイムソフトウェアのインストール先ディレクトリ (JavaTM 2 Runtime Environment のトップレベルディレクトリまたは JavaTM 2 SDK ソフトウェアの jre ディレクトリ) を指します。 Java 2 SDK, v 1.4 に含まれる強力な暗号化機能のバージョンを機能無制限のバージョンと簡単に置き換えることができるように、これらのファイルは標準的な位置に移動されました。

不要になった JCE フレームワークのプロバイダ認証

JCE 1.2.1 では、プラグインする JCE の完全性および信頼性を保証するため、JCE フレームワークの認証用コードをプロバイダに含める必要がありました。 JCE が Java 2 SDK, v 1.4 に統合されることにより、この操作は不要になりました。

「How to Implement a Provider for the Java Cryptography Extension 1.2.1」 のガイダンスに従う JCE 1.2.1 プロバイダは、Java 2 SDK, v 1.4 の JCE フレームワークでも引き続き使用できます。

しかし、JCE 1.2.1 の JCE プロバイダドキュメント (前述) の推奨条件に従わず、保護ドメインから JCE フレームワークを特定するようなフレームワーク認証コードを持つプロバイダは、Java 2 SDK, v 1.4 では使用できません。 JCE が Java 2 SDK, v 1.4 に統合されたため、JCE フレームワークは、Java 2 SDK, v 1.4 のその他のクラスと同様に null コードのソースを持つようになりました。 推奨条件に従ってフレームワークの認証を実施できるように、プロバイダを変更できます。また、条件式を挿入して、プロバイダを JCE 1.2.1 で使用する場合以外はフレームワーク認証コードが実行されないようにすることもできます。

PKCS #1、#5、#8 の追加機能のサポート

JCE と JCA が拡張され、PKCS #1、#5、#8 の追加機能をサポートするようになりました。追加されたクラスは以下のとおりです。

javax.crypto.spec.PBEKeySpec クラスに追加されたメソッドは以下のとおりです。

public PBEKeySpec(char[] password, byte[] salt, 
    int iterationCount, int keyLength)
public PBEKeySpec(char[] password, byte[] salt, 
    int iterationCount)
public final void clearPassword()
public final byte[] getSalt()
public final int getIterationCount()
public final int getKeyLength()

SunJCE Blowfish のデフォルトキーサイズの変更

SunJCE プロバイダの Blowfish アルゴリズム用デフォルトキーサイズは、56 バイトから 56 ビットに変更されました。


暗号化の概要

このセクションでは、API により実装される概念、および API 仕様で使用される技術用語の正確な意味に関する高度な説明を提供します。

暗号化および暗号解読

暗号化とは、データ (「クリアテキスト」と呼ばれる) および短い文字列 (「キー」) を受け取って、鍵を知らないサードパーティにとって無意味なデータ (「暗号テキスト) を生成する処理です。 暗号解読とはその逆で、暗号テキストおよび短い鍵文字列を受け取り、クリアテキストを生成する処理です。

パスワードベース暗号化

パスワードベース暗号化 (PBE) では、パスワードから暗号化鍵を導き出します。パスワードから暗号化鍵を取得しようとする攻撃者のタスクを非常に時間のかかるものにするため、大半の PBE 実装では、キーの作成時に乱数への混入 (salt と呼ばれる) が行われます。

暗号

暗号化および暗号解読は、暗号を使って行われます。暗号とは、暗号化方式に従って暗号化および暗号解読を実行可能なオブジェクトのことです。

鍵協定

鍵協定とは、複数のパーティが秘密情報を交換しなくても同じ暗号化鍵を確立可能なプロトコルを指します。

メッセージ認証コード

メッセージ認証コード (MAC) は、信頼できない媒体に送信または格納された情報の完全性を、秘密鍵に基づいてチェックする方法を提供します。一般に、メッセージ認証コードは、秘密鍵を共有する 2 つのパーティ間で送信される情報の有効性を検証する場合に使用されます。

暗号化ハッシュ機能に基づくMAC 機構は、HMAC と呼ばれます。HMAC は、秘密共有鍵と組み合わせて、MD5 や SHA-1 などの任意の暗号化ハッシュ機能で使用できます。HMAC については、RFC 2104 で規定されています。


コアクラス


アプリケーションの暗号化制限の「免責」を取得する方法

[注 1:大半のアプリケーション開発者には、このセクションで説明する内容は関係ありません。関係があるのは、作成するアプリケーションが、政府により暗号化制限の課された国に輸出される可能性があり、アプリケーションをその制限に適合させる必要がある場合だけです。この節を省略する場合は、Installing JCE Providers for the Java 2 SDK, v 1.4 へ進んでください。]

[注 2:このセクション全体で、「アプリケーション」という語は、アプリケーションとアプレットの両方を指します。]

Java 2 SDK, v 1.4 の JCE フレームワークには、異なる管轄コンテキスト (位置) のアプレット/アプリケーションから利用可能な暗号化アルゴリズムおよび最大暗号化強度に関する制限を施行する機能が含まれます。これらの制限はすべて、「管轄ポリシーファイル」に指定されます。

輸入管理制限があるため、Java 2 SDK, v 1.4 に同梱された管轄ポリシーファイルは「強固」ですが、暗号化の使用には制限があります。適格国 (大半の国が該当) の在住者は、暗号化機能に制限のない「強度無制限」のバージョンを利用できます。ただし、政府が制限を課しているこれらの国が輸入できるのは「強力な」バージョンだけです。JCE フレームワークでは、インストール済みの管轄ポリシーファイルで指定された制限が施行されます。

これらの国の一部またはすべてで、特定のアプリケーションに対し、暗号化制限の一部またはすべての免責が許可されています。たとえば、特定の種類のアプリケーションは「特別」と見なされ、免責されます。また、鍵復元などの「免責機構」を利用するアプリケーションは、免責可能です。この種の国では、免責されたと見なされるアプリケーションは、免責されていないアプリケーションに許可されるよりも強力な暗号化にアクセスできます。

実行時にアプリケーションが「免責されている」と認識されるようにするには、次の条件を満たす必要があります。

以下に、暗号化制限の一部またはすべての免責をアプリケーションに設定するために必要な手順のサンプルを示します。これは、免責されたものとしてアプリケーションを認識および処理するため、JCE により要求される情報を含む、基本情報です。実際には、アプリケーションを実行可能にする (政府が暗号化制限を課している) 特定の国の免責要件を知る必要があります。また、免責されたアプリケーションの処理プロセスを保持する JCE フレームワークベンダーの要件も理解しておく必要があります。詳細は、ベンダーにお尋ねください。なお、SunJCE プロバイダは、ExemptionMechanismSpi クラスの実装を提供しません。


免責機構を使用するアプリケーションに対する特殊コード要件

アプリケーションが関連付けられたアクセス権ポリシーファイルを (同じ 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 1.4 とともにダウンロードされる管轄ポリシーファイルの書式と同じです。以下にその書式を示します。

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 の最大キーサイズおよびアルゴリズムパラメータ値は、免責アクセス権エントリにより決定されます。

アプリケーションにバンドルされるアクセス権ポリシーファイル内の関連するエントリに、暗黙的に設定された免責アクセス権が存在しない場合、またはいずれかの登録済みプロバイダから利用可能な、指定された免責機構の実装が存在しない場合、デフォルトの標準暗号化アクセス権のみがアプリケーションに付与されます。


Java 2 SDK, v 1.4 対応 JCE プロバイダのインストール

暗号化プロバイダを使用するには、静的または動的にインストールおよび登録する必要があります。 Java 2 SDK, v 1.4 の JCE 用暗号化プロバイダのインストールおよび構成方法は、Java TM 2 プラットフォームの他のプロバイダと同様です。プロバイダのインストールおよび構成方法の詳細は、「JavaTM 暗号化アーキテクチャ API 仕様 & リファレンス」の「プロバイダのインストール」を参照してください。

「SunJCE」はあらかじめインストールされているため、インストールする必要はありません。他のプロバイダを使用する場合は、後述のセクションでプロバイダの登録方法を確認してください。

プロバイダのインストールには、プロバイダパッケージクラスのインストール、およびプロバイダの構成という 2 つのステップが含まれます。状況によっては、使用する前に、プロバイダのアクセス権の設定が必要な場合があります。

プロバイダクラスのインストール

最初に行う事柄は、プロバイダクラスを利用可能にして、要求時に検出できるようにすることです。プロバイダクラスは、署名付き JAR (Java ARchive) ファイル形式で提供されます。

プロバイダクラスのインストール方法は 2 種類あります。

プロバイダ JAR ファイルは、以下に示すインストール型拡張機能 JAR ファイルの標準位置に配置された場合、「インストール型」拡張機能と見なされます。

<java-home>/lib/ext         [Solaris]
<java-home>¥lib¥ext         [Win32]

ここで、<java-home> は、ランタイムソフトウェアのインストール先ディレクトリ (JavaTM 2 Runtime Environment のトップレベルディレクトリまたは JavaTM 2 SDK ソフトウェアの jre ディレクトリ) を指します。 たとえば、Java 2 SDK, v 1.4 を /home/user1/Java 2 SDK1.4.0 ディレクトリ (Solaris)、または C:¥Java 2 SDK1.4.0 ディレクトリ (Win32) にインストールした場合、JAR ファイルを次のディレクトリにインストールする必要があります。

/home/user1/Java 2 SDK1.4.0/jre/lib/ext    [Solaris]
C:¥Java 2 SDK1.4.0¥jre¥lib¥ext             [Win32]

同様に、JRE, v 1.4 を /home/user1/j2re1.4.0 ディレクトリ (Solaris)、または C:¥j2re1.4.0 ディレクトリ (Win32) にインストールした場合、JAR ファイルを次のディレクトリにインストールする必要があります。

/home/user1/j2re1.4.0/lib/ext         [Solaris]
C:¥j2re1.4.0¥lib¥ext                  [Win32]

詳細については、「拡張機構アーキテクチャ」仕様の「インストール型拡張機能」「バンドル型拡張機能」のセクションを参照してください。

プロバイダの構成

次の手順では、認可プロバイダのリストにこのプロバイダを追加します。これは、セキュリティプロパティファイルを編集することにより、静的に行われます。

<java-home>/lib/security/java.security         [Solaris]
<java-home>¥lib¥security¥java.security         [Win32]

ここで、<java-home> は JRE がインストールされているディレクトリを指します。 たとえば、Java 2 SDK バージョン 1.4 を /home/user1/Java 2 SDK1.4.0 (Solaris) または C:¥Java 2 SDK1.4.0 (Win32) にインストールしている場合は、次のファイルを編集する必要があります。

/home/user1/Java 2 SDK1.4.0/jre/lib/security/java.security  [Solaris]
C:¥Java 2 SDK1.4.0¥jre¥lib¥security¥java.security           [Win32]

同様に、Java 2 Runtime Environment バージョン 1.4 を Solaris の /home/user1/j2re1.4.0 ディレクトリにインストールしている場合、または Win32 の C:¥j2re1.4.0 ディレクトリにインストールしている場合は、次のファイルを編集する必要があります。

/home/user1/j2re1.4.0/lib/security/java.security       [Solaris]
C:¥j2re1.4.0¥lib¥security¥java.security                [Win32]

プロバイダごとに、このファイルは次の形式の文を保持します。

    security.provider.n=masterClassName

これはプロバイダを宣言し、その優先順位 n を指定します。優先順位とは、特定プロバイダの指定がないときに、要求されたアルゴリズムについてプロバイダを検索する順序です。順位は 1 から始まり、1 が最優先で次に 2、3 ...と続きます。

masterClassName には、プロバイダの「マスタークラス」を完全修飾名で指定します。この名前は、プロバイダベンダーから入手する必要があります。

Java 2 SDK, v 1.4 には、「SUN」という名前のプロバイダが標準で搭載されています。このプロバイダは、次に示すように、静的プロバイダとして java.security プロパティファイル内で自動的に構成されます。

security.provider.1=sun.security.provider.Sun

「SUN」プロバイダのマスタークラスは、sun.security.provider パッケージ内の Sun クラスです。

JCE プロバイダ「SunJCE」および Java 2 プラットフォームに含まれる他のセキュリティ関連プロバイダは、静的プロバイダとして自動的に構成されます。

別の JCE プロバイダを利用する場合、代替プロバイダを登録する行を追加し、優先順位を適切に設定します (必要に応じて他のプロバイダの順序も調整)。

登録するプロバイダのマスタークラスが com.cryptox.provider パッケージの CryptoX クラスで、このプロバイダを優先順位の第 2 位にする場合を考えましょう。その場合、java.security ファイルにある「SUN」プロバイダの行の下に次の行を追加して、さらに他のプロバイダの優先順位を 2 より大きくします。

    security.provider.2=com.cryptox.provider.CryptoX
注:プロバイダは、動的に登録することもできます。このためには、Security クラスの addProvider または insertProviderAt のどちらかのメソッドを呼び出します。こうした登録は持続的なものではありません。また、実行できるのは次の権限を付与されたコードだけです。
java.security.SecurityPermission "insertProvider.{name}"
ここで、{name} には実際のプロバイダ名を指定します。たとえば、プロバイダ名が「MyJCE」であり、このプロバイダを動的に登録するコードが /localWork ディレクトリの MyApp.jar ファイル内に存在する場合、アクセス権を付与するサンプルポリシーファイルの grant 文は次のようになります。
grant codeBase "file:/localWork/MyApp.jar" {
  permission java.security.SecurityPermission
      "insertProvider.MyJCE";
};

プロバイダアクセス権の設定

JCE プロバイダがインストール型拡張機能ではない場合、セキュリティマネージャがインストール済みの状態で、JCE を使用するアプレットまたはアプリケーションを実行する際、常に JCE プロバイダに アクセス権を付与する必要があります。通常、アプレットの実行時にはセキュリティマネージャが常にインストールされます。アプリケーションの場合でも、アプリケーション自体のコード内またはコマンド行引数で指定することにより、セキュリティマネージャをインストールできます。デフォルトシステムのポリシー構成ファイルは、インストール型拡張機能にすべてのアクセス権を付与するため、インストール型拡張機能にアクセス権を設定する必要はありません。

ベンダーの提供する各プロバイダ用ドキュメントには、必須のアクセス権やそれを付与する方法が記載されています。たとえば、拡張機能がインストール型ではなく、セキュリティマネージャがインストールされている場合、プロバイダに次のアクセス権を付与する必要があります。

たとえば、名前が「MyJCE」で、コードが myjce_provider.jar 内に存在するプロバイダにアクセス権を付与するサンプルコードを次に示します。この種の文は、ポリシーファイルに記述されます。この例では、myjce_provider.jar ファイルは /localWork ディレクトリに格納されるものとします。

grant codeBase "file:/localWork/myjce_provider.jar" {
  permission java.lang.RuntimePermission "getProtectionDomain";
  permission java.security.SecurityPermission
      "putProviderProperty.MyJCE";
};

JCE キーストア

「SunJCE」プロバイダは、Java 2 SDK, v 1.4 の java.security.KeyStore クラスの実装を独自に提供します。 この実装は、(トリプル DES に対しパスワードベース暗号化を使用して) Java 2 SDK, v 1.4 の「SUN」プロバイダが提供するキーストア実装よりも強力に非公開鍵を保護します。 Java 2 SDK, v 1.4 の配布は、世界規模およびバイナリおよびソース形式で行われるため、これより強力な暗号化機構は使用できません。

「SunJCE」プロバイダのキーストア実装のメリットを享受するには、キーストア型に「JCEKS」を指定します。

「JKS」型 (Java 2 SDK の「SUN」プロバイダにより実装されたキーストア型の名前) のキーストアを、JCE キーストア型「JCEKS」にアップグレードできます。これは、キーストア内の非公開鍵エントリのパスワードを変更することにより実行します。

「SunJCE」の提供する (より) 強力な暗号化による鍵保護を、デフォルトキーストア内の「signkey」という名前の非公開鍵に適用する場合は、次のコマンドを入力します。このコマンドにより、旧パスワードおよび新規パスワードの指定が求められます。

    keytool -keypasswd -alias signkey -storetype jceks

同じコマンドを使用して、パスワードを以前の値に戻すこともできます。

keytool とキーストア、およびその管理方法の詳細は、「セキュリティツール」を参照してください。


コード例

このセクションでは、Java 2 SDK, v 1.4 の 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);

cleartextcleartext1 は、同一です。

パスワードベース暗号化の使用

この例では、ユーザにパスワードを要求し、暗号化鍵をそのパスワードから導き出します。

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」を参照してください。


付録 A:標準名

JCE API では、アルゴリズム、アルゴリズムモード、およびパディング方式の標準名のセットが必要とされ、使用されます。ここに記載の仕様は、標準名として以下の名前を確立するものです。また、「JavaTM 暗号化アーキテクチャ仕様 & リファレンス」の「付録 A」で定義された標準名のリストを補足する内容となっています。 アルゴリズム名の大文字と小文字が区別されることに留意してください。

場合によっては、命名規則を利用して、名前がリストに明示的に表示されないようにすることをお勧めします。こうしておけば、プロバイダ実装が異なっていても名前の整合性を確保しやすくなります。 <digest>、<encryption> のように角括弧で囲まれた項目は、特定のメッセージダイジェスト、暗号化アルゴリズム、その他の名前で置き換えられます。

暗号

アルゴリズム

Cipher のインスタンスを要求する場合、次の名前を変換内の algorithm コンポーネントとして指定できます。

  • AES - Advanced Encryption Standard として、NIST によって FIPS ドラフトに指定されました。 Joan Daemen、Vincent Rijmen 両氏による Rijndael アルゴリズムに基づいた 128 ビットのブロック暗号であり、128 ビット、192 ビット、256 ビットの鍵をサポートします。

  • Blowfish - Bruce Schneier 氏の設計によるブロック暗号です。

  • DES - データ暗号化規格です (FIPS PUB 46-2 で定義)。

  • DESede - トリプル DES 暗号化です (DES-EDE)。

  • 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 に定義されたパスワードベースの暗号化アルゴリズムです。

  • RC2RC4、および 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 コンポーネントとして指定できます。

  • NoPadding - パディングなし

  • OAEPWith<digest>And<mgf>Padding - PKCS #1 に定義されている Optimal Asymmetric Encryption Padding スキーマ。<digest> はメッセージダイジェスト、<mgf> はマスク生成関数で置き換える (例: OAEPWithMD5AndMGF1Padding)

  • 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 のインスタンスを要求する際、次のアルゴリズム名を指定できます。

KeyGenerator

KeyGenerator のインスタンスを要求する際、次のアルゴリズム名を指定できます。

KeyPairGenerator

KeyPairGenerator のインスタンスを要求する際、次のアルゴリズム名を指定できます。

SecretKeyFactory

SecretKeyFactory のインスタンスを要求する際、次のアルゴリズム名を指定できます。

KeyFactory

KeyFactory のインスタンスを要求する際、次のアルゴリズム名を指定できます。

AlgorithmParameterGenerator

AlgorithmParameterGenerator のインスタンスを要求する際、次のアルゴリズム名を指定できます。

AlgorithmParameters

AlgorithmParameters のインスタンスを要求する際、次のアルゴリズム名を指定できます。

MAC

Mac のインスタンスを要求する際、次のアルゴリズム名を指定できます。

キーストア型

KeyStore のインスタンスを要求する際、次の型を指定できます。

免責機構

暗号化制限を「免責された」と見なされるアプリケーションに付属するアクセス権ポリシーファイル内で、次の免責機構名を指定できます。


付録 B:SunJCE のデフォルトキーサイズ

SunJCE プロバイダは、次のデフォルトキーサイズを使用します。


付録 C:SunJCE のキーサイズ制限

SunJCE プロバイダでは、次のクラスの初期化メソッドに渡すキーサイズに制限が課されます。


付録 D:管轄ポリシーファイルの形式

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 オブジェクトの構築用パラメータリストも指定する必要があります。

アクセス権エントリの各項目は、指定された順序で記述する必要があります。各エントリはセミコロンで終わります。

識別子 (grantpermission) では大文字と小文字は区別されませんが、<crypto permission class name>、および値として引き渡される文字列では大文字と小文字が区別されます。

注:「*」は、すべてのアクセス権エントリオプションでワイルドカードとして使用できます。たとえば、<alg_name> に「*」を指定すると、「すべてのアルゴリズム」という意味になります。


付録 E:「強力」な管轄ポリシーファイルにより許可される最大キーサイズ

輸入管理制限により Java 2 SDK, v 1.4 に同梱されている管轄ポリシーファイルでは、制限付きの「強力」な暗号化機能が利用できます。

アルゴリズム

最大キーサイズ

DES

64

DESede

*

RC2

128

RC4

128

RC5

128

RSA

2048

* (その他すべて)

128


付録 F:サンプルプログラム


Copyright ©1996-2002 Sun Microsystems, Inc.All Rights Reserved.

コメントの送付先:java-security@java.sun.com
Sun
Java ソフトウェア
最終更新日: 2002 年 1 月 10 日