JavaTM 暗号化拡張機能 (JCE)

リファレンスガイド

JavaTM 2 Platform Standard Edition Development Kit (JDK) 5.0



はじめに


JDK 5.0 における JCE の新機能


暗号化の概要

暗号化および暗号解読

パスワードベース暗号化

暗号

鍵協定

メッセージ認証コード


コアクラス

Cipher クラス

Cipher Stream クラス

CipherInputStream クラス

CipherOutputStream クラス

KeyGenerator クラス

SecretKeyFactory クラス

SealedObject クラス

KeyAgreement クラス

Mac クラス


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


JDK 5.0 での 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 1.4 リリース以降では JCE が統合されています。

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

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

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

用語に関する注記

JDK 5.0 の JCE には、2 つのソフトウェアコンポーネントがあります。

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

JDK 5.0 における JCE の新機能

JCE v1.4 と 5.0 の相違点を次に示します。

PKCS #11 ベースの暗号プロバイダのサポート

JDK 5.0 では、ネイティブの PKCS#11 API に対する汎用ゲートウェイとして動作する JCA/JCE プロバイダ、SunPKCS11 が実装されました。PKCS #11 は暗号アクセラレータのデファクトスタンダードで、暗号化スマートカードへのアクセスに広く使用されています。管理者およびユーザは、このプロバイダを設 定して、任意の PKCS#1 v2.x 互換トークンと通信できます。

設定ファイル形式の例を示します。

Solaris 暗号化フレームワークの統合

デフォルトの Java セキュリティプロバイダ設定が JDK 5.0 で変更され、Solaris 10 では Solaris 暗号化フレームワークを使用する SunPKCS11 プロバイダのインスタンスが含まれるようになりました。これは最高の優先度をもつプロバイダで、既存のアプリケーションすべてが Solaris 10 でパフォーマンス向上のメリットを享受できます。Solaris 8 および Solaris 9 での動作に変更はありません。

この変更のため、すべての Solaris 10 システムでは、多くの暗号化演算が以前の何倍もの速度で実行されるようになります。暗号によるハードウェア高速化を搭載したシステムでは、100 倍のパフォーマンス向上を見込めます。

ECC アルゴリズムのサポート

JDK 5.0 より前では、JCA/JCE フレームワークでは、ECC 関連の暗号化アルゴリズムのクラスはサポートされていませんでした。ECC を利用するユーザは、ECC を実装したサードパーティのライブラリに頼らなければなりませんでした。しかし、このようなライブラリは既存の JCA/JCE フレームワークとはうまく統合されませんでした。

JDK 5.0 以降は、ECC をサポートするプロバイダ用の ECC クラスが完全にサポートされるようになりました。

次のインタフェースが追加されました。

次のクラスが追加されました。

ByteBuffer API サポートの追加

ByteBuffer 引数をとるメソッドが、バルクデータの処理に使用する JCE API および SPI クラスに追加されました。ByteBuffer を byte[] より効率的に処理できる場合、プロバイダは engine* メソッドをオーバーライドできます。

次の JCE メソッドが ByteBuffer のサポートのために追加されました。

    javax.crypto.Mac.update(ByteBuffer input)
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)
次の JCA メソッドが ByteBuffer のサポートのために追加されました。
    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 のサポート

JDK 5.0 では RC2 アルゴリズム実装が拡張され、入力された鍵の長さとは異なる有効な鍵サイズをサポートします。

XML 暗号化 RSA-OAEP アルゴリズムの完全サポート

JDK 5.0 より前の JCE では、PKCS#1 v2.1 および W3C Recommendation for XML Encryption の RSA-OAEP 鍵転送アルゴリズムに定義されているように、OAEP および PSS パディングで使用されるデフォルト以外の値を指定するパラメータクラスが定義されていませんでした。したがって、OAEP および PSS パディングに使用されたデフォルト以外の値をアプリケーションで指定する一般的な方法はありませんでした。

JDK 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 の取得の簡略化

JDK 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 インスタンスが、暗号化管轄ファイルで許容された最大値を超える鍵 (またはある種の暗号アルゴリズムのパラメータ) で初期化されると、例外がスローされます。

JDK 5.0 では、Cipher クラスが更新され、管轄ポリシーファイルで設定された鍵の最大長およびパラメータを定義するようになったため、デフォルトの (強度の制限された) 管轄ポリシーファイルがインストールされている場合、アプリケーションはより短かい鍵を使用できます。

次のメソッドが javax.crypto.Cipher に追加されました。

    public static final int getMaxAllowedKeyLength(String transformation)
throws NoSuchAlgorithmException

public static final AlgorithmParameterSpec
getMaxAllowedParameterSpec(String transformation)
throws NoSuchAlgorithmException;

HmacSHA256、HmacSHA384、および HmacSHA512 のサポート

HmacSHA-256、HmacSHA-384、および HmacSHA-512 アルゴリズムのサポートが JDK 5.0 で追加されました。

SunJCE プロバイダへの RSA 暗号のサポート

パブリックにアクセスできる RSA 暗号化実装が、SunJCE プロバイダに追加されました。

SunJCE プロバイダへの RC2 および ARCFOUR 暗号のサポート

SunJCE プロバイダに、RC2 (RFC 2268) および ARCFOUR (RC4TM 互換アルゴリズム) 暗号が実装されました。

「PBEWithSHA1AndDESede」と「PBEWithSHA1AndRC2_40」暗号 のサポート

SunJCE プロバイダに、PBEWithSHA1AndDESede と PBEWithSHA1AndRC2_40 暗号のサポートが追加されました。

JCE Block Encryption 暗号での XML Encryption Padding アルゴリズムのサポート

W3C XML 暗号で、新しいパディングアルゴリズム、ブロック暗号に対する「ISO10126Padding」が定義されます。詳細については、「5.2 Block Encryption Algorithms」を参照してください。

Sun のプロバイダを XML 暗号実装よび JSR 106 プロバイダで使用できるようにするため、JDK 5.0 ではこのパディングに対するサポートが追加されました。

暗号化の概要

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

暗号化および暗号解読

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

パスワードベース暗号化

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

暗号

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

鍵協定

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

メッセージ認証コード

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

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


コアクラス


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

注 1: 大半のアプリケーション開発者には、このセクションで説明する内容は関係ありません。関係があるのは、作成するアプリケーションが、政府により暗号化制限 の課された国に輸出される可能性があり、アプリケーションをその制限に適合させる必要がある場合だけです。このセクションをスキップして、「JDK 5.0 での JCE プロバイダのインストール」に進むこともできます。
注 2: このセクション全体で、「アプリケーション」という語は、アプリケーションとアプレットの両方を指します。

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

輸入制御の制限された国が存在するため、Sun Microsystems の JDK 5.0 に同梱される管轄ポリシーファイルでは、「強力」ではあっても制限付きの暗号化が使用可能になっています。適格国 (大半の国が該当) の在住者は、暗号化機能に制限のない「強度無制限」のバージョンを利用できます。ただし、政府が制限を課しているこれらの国が輸入できるのは「強力な」 バージョンだけです。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 にする必要があります。

免責されるアプリケーションにバンドルされるアクセス権ポリシーファイル内のアクセス権エントリの書式は、JDK 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 の最大キーサイズおよびアルゴリズムパラメータ値は、免責アクセス権エントリにより決定されます。

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


JDK 5.0 での JCE プロバイダのインストール

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

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

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

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

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

プロバイダクラスのインストールには、次の 2 つの方法があります。

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

<java-home>/lib/ext         [Solaris]
<java-home>\lib\ext [Windows]

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

/home/user1/JDK1.5.0/jre/lib/ext    [Solaris]
C:\JDK1.5.0\jre\lib\ext [Windows]

同様に、JRE 5.0 を /home/user1/jre1.5.0 ディレクトリ (Solaris)、または C:\jre1.5.0 ディレクトリ (Microsoft Windows) にインストールした場合、JAR ファイルを次のディレクトリにインストールする必要があります。

/home/user1/jre1.5.0/lib/ext         [Solaris]
C:\jre1.5.0\lib\ext [Windows]

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

プロバイダの構成

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

<java-home>/lib/security/java.security     [Solaris]
<java-home>\lib\security\java.security [Windows]

ここで、<java-home> は JRE がインストールされているディレクトリを指します。たとえば、JDK 5.0 を /home/user1/JDK1.5.0 ディレクトリ (Solaris)、または C:\JDK1.5.0 ディレクトリ (Microsoft Windows) にインストールした場合、次のファイルを編集する必要があります。

/home/user1/JDK1.5.0/jre/lib/security/java.security  [Solaris]
C:\JDK1.5.0\jre\lib\security\java.security [Windows]

同様に、Java 2 Runtime Environment v 1.4 を /home/user1/jre1.5.0 ディレクトリ (Solaris) または C:\jre1.5.0 ディレクトリ (Microsoft Windows ) にインストールしている場合は、次のファイルを編集する必要があります。

/home/user1/jre1.5.0/lib/security/java.security       [Solaris]
C:\jre1.5.0\lib\security\java.security [Windows]

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

    security.provider.n=masterClassName

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

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

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

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

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

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

    keytool -keypasswd -alias signkey -storetype jceks

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

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


コード例

このセクションでは、JDK 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);

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 暗号化アーキテクチャ 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 Cryptography 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 コンポーネントとして指定できます。

  • 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> はマスク生成関数で置き換える(例: 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: 「強力」な管轄ポリシーファイルにより許可される最大キーサイズ

輸入制御上の制限のために、JDK 5.0 に同梱される管轄ポリシーファイルでは、「強力」ではあっても制限付きの暗号化の使用が許可されます。以下に、この「強力な」バージョンの管轄ポリシー ファイルで許可される最大キーサイズを示します。

アルゴリズム

最大キーサイズ

DES

64

DESede

*

RC2

128

RC4

128

RC5

128

RSA

2048

* (その他すべて)

128


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