| Oracle® Fusion Middleware Oracle Security Developer Toolsによるアプリケーションの開発 12c (12.2.1) E72521-01 |
|
前 |
次 |
この章には次のトピックが含まれます:
Oracle CMS SDKは、CMSオブジェクトの読取りと書込みのためのツール、サンプル・プログラム、および安全なメッセージ・エンベロープを開発するためのサポート・ツールなど、豊富なツールを含むPure Java APIです。
Oracle CMSでは、RFC 2630に規定されているIETF暗号メッセージ構文が実装されます。この構文は、メッセージのデジタル署名、ダイジェスト、認証および暗号化に使用されます。
暗号メッセージ構文は、RFC 2315[PKCS#7]に指定されているように、PKCS #7バージョン1.5から導出されています。
関連項目:
この仕様へのリンクは、「リファレンス」を参照してください。
Oracle CMSでは、署名付きデータ、エンベロープ・データ、暗号化データなど、様々なコンテンツ・タイプがサポートされます。
Oracle CMSでは、表4-1に示すように、RFC 2630に指定されているすべてのコンテンツ・タイプがサポートされます。
表4-1 Oracle CMSでサポートされるコンテンツ・タイプ
| タイプ | 識別子 |
|---|---|
データ |
1.2.840.113549.1.7.1 |
signed-data |
1.2.840.113549.1.7.2 |
enveloped-data |
1.2.840.113549.1.7.3 |
digested-data |
1.2.840.113549.1.7.5 |
encrypted-data |
1.2.840.113549.1.7.6 |
authenticated-data |
1.2.840.113549.1.9.16.1.2 |
Oracle CMSはRFC 2630を完全実装していますが、次の例外があります。
属性証明書はサポートされません。
鍵合意のRecipientInfoはサポートされません。
Oracle CMSでは、RFC 2634に指定されているS/MIMEコンテンツ・タイプに対する拡張セキュリティ・サービスがサポートされます。
| タイプ | 識別子 |
|---|---|
receipt |
1.2.840.113549.1.9.16.1.2 |
次の、RFC 3161に対応するIETF PKIXタイムスタンプ・プロトコルのコンテンツ・タイプもサポートされます。
| タイプ | 識別子 |
|---|---|
TSTInfo |
1.2.840.113549.1.9.16.1.4 |
注意:
Oracle CMS では、これまでに説明したコンテンツ・タイプ以外は処理されません。
RFC 3161へのリンクは、「リファレンス」を参照してください。
Oracle CMSは、次の点でPKCS #7 v 1.5 [RFC 2315]およびIETF CMS [RFC 2630]と異なります。
enveloped-dataにオプションのOriginatorInfoが含まれます。
RFC 2630では、エンベロープ・データに、保護されていないオプションの属性も含まれます。
signed-dataであるSignerInfoのSignerIdentifierとして、IssuerAndSerialNoまたはSubjectKeyIdentifierを選択できます。
RFC 2630では、署名付きデータにencapsulatedcontentinfoが含まれます。encapsulatedcontentinfoにはオプションのコンテンツが含まれますが、RFC 2315にはコンテンツ・データが含まれます。
注意:
PKCS#7実装との相互運用性が必要な場合は、これらの違いに注意してください。
Oracleセキュリティ開発ツールは、Oracle WebLogic ServerとともにORACLE_HOMEにインストールされます。
Oracle CMSを使用するには、システムにJava Development Kit (JDK)バージョン1.6以上が必要です。
CLASSPATH環境変数には、必要なjarファイルおよびclassファイルすべてのフルパスとファイル名を指定してください。次の項目をCLASSPATHに指定します。
osdt_core.jarファイル
osdt_cert.jarファイル
osdt_cms.jarファイル
たとえば、CLASSPATHは次のようになります。
%CLASSPATH%; %ORACLE_HOME%\modules\oracle.osdt_11.1.1\osdt_core.jar; %ORACLE_HOME%\modules\oracle.osdt_11.1.1\osdt_cert.jar; %ORACLE_HOME%\modules\oracle.osdt_11.1.1\osdt_cms.jar;
この項では、Oracle CMSのクラスについて紹介し、それにより使用可能になるCMSオブジェクトの開発に対する様々なアプローチと、オブジェクトの使用方法について説明します。
この項の内容は次のとおりです。
oracle.security.crypto.cmsパッケージでCMSオブジェクトの読取りと書込みを行うには、次の2つの方法があります。
CMSContentInfoクラスの使用。比較的簡単に使用できます。
次のいずれかのクラスの使用:
CMSInputStream
CMSOutputStream
CMSInputConnector
CMSOutputConnector
これらのクラスでは、CMSオブジェクトのシングル・パスでの読取りおよび書込み機能が提供され、出力を書き込む前に入力データを累積する必要がありません。
Oracle CMSのAPIを使用すると、ネスト(ラップ)されたCMSオブジェクトを構築できます。ラップ数の制限はありません。
アプリケーション開発者は、特定のCMSオブジェクト・タイプに注意する必要があります。これらについては、この後の項で説明します。
デタッチされたオブジェクトは、dataおよびreceiptコンテンツ・タイプに適用されます。これらのタイプでは、デタッチされたオブジェクトは保護されるコンテンツがないオブジェクトです。
デジェネレート・オブジェクトは、証明書専用のsigned-dataオブジェクトであり、signed-dataコンテンツ・タイプのみに定義されます。signed-dataオブジェクトに署名者がいない場合に該当します。通常は証明書の格納に使用され、ファイル拡張子p7bおよびp7cが関連付けられます。
外部署名はsigned-dataコンテンツ・タイプのみに定義されます。これは、基本的にはデタッチされたsigned-dataオブジェクトです。つまり、signed-dataオブジェクトには1名以上の署名者がありますが、署名付きコンテンツがsigned-dataオブジェクトに存在しません。
表4-2に、CMS***ContentInfoクラスを構成するクラスを示します。
表4-2 CMS***ContentInfoクラス
| クラス | コンテンツ・タイプ |
|---|---|
CMSDataContentInfo |
CMS.id_data |
ESSReceipt |
CMS.id_ct_receipt (RFC 2634のreceipt) |
CMSDigestedDataContentInfo |
CMS.id_digestedData |
CMSSignedDataContentInfo |
CMS.id_signedData |
CMSEncryptedDataContentInfo |
CMS.id_encryptedData |
CMSEnvelopedDataContentInfo |
CMS.id_envelopedData |
CMSAuthenticateDataContentInfo |
CMS.id_ct_authData |
これらのクラスは次の場合に使用できます。
適切なコンテンツ・タイプのオブジェクトの読取りおよび書込み
デタッチされたオブジェクトの構成と処理
ネストしたオブジェクトの作成
CMS***ContentInfoクラスについては、次の各項で詳しく説明します。
CMSContentInfoは、基本的なCMSオブジェクトを表す抽象クラスです。表4-2に、CMSContentInfoのサブクラスを示しています。
この抽象クラスの有用なメソッドの一部を、表4-3に示します。
表4-3 CMSContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
contentTypeName (oracle.security.crypto.asn1.ASN1ObjectID contentType) |
オブジェクトのコンテンツ・タイプを文字列として返します。 |
getContentType() |
オブジェクトのコンテンツ・タイプをオブジェクト識別子(OID)として返します。 |
input(java.io.InputStream is) |
指定した入力ストリームからBERエンコーディングを読み取ることで、このオブジェクトを初期化します。 |
inputInstance(java.io.InputStream is) |
指定した入力ストリームからBERエンコーディングを読み取ることで、新しいCMSContentInfoオブジェクトを作成します。 |
isDegenerate() |
オブジェクトがデジェネレートかどうかを示します。 |
isDetached() |
オブジェクトがデタッチされているかどうかを示します。 |
output(java.io.OutputStream os) |
オブジェクトのエンコーディングを所定の出力ストリームに書き込みます。 |
コンテンツ・タイプを指定してCMSContentInfoオブジェクトを作成できます。
CMSオブジェクトを構成する手順を次に示します。
output(..)メソッドをコールして、オブジェクト・エンコーディングを書き込みます。新しいオブジェクトを作成するには、作業している具体サブクラスのいずれかのコンストラクタを使用します。
クラスCMSDataContentInfoは、定数CMS.id_dataで定義されるid-dataタイプのオブジェクトを表し、任意の8ビット文字列を指します(文字列の解釈はアプリケーションに任されます)。
このクラスの有用なメソッドを次に示します。
byte[] getData()
これは、dataオブジェクトに格納されているデータを返します。
CMS dataオブジェクトを作成する手順を次に示します。
情報を含むバイト配列documentBytesをとるコンストラクタを使用して、次のようにCMSDataContentInfoのインスタンスを作成します。
CMSDataContentInfo exdata = new CMSDataContentInfo(byte[] documentBytes)
dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
exdata.output(new FileOutputStream("data.p7m"));
CMS dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
クラスESSReceiptは、定数CMS.id_ct_receiptで定義されるid-ct-receiptタイプのオブジェクトを表し、RFC 2634のreceiptを指します。
表4-4に、このクラスの有用なメソッドの一部を示します。
表4-4 ESSReceiptの有用なメソッド
| メソッド | 説明 |
|---|---|
byte[] getOriginatorSignatureValue() |
このreceiptの生成の原因となったメッセージの署名値を返します。 |
ASN1ObjectID getReceiptContentType() |
このreceiptの生成の原因となったメッセージのコンテンツ・タイプを返します。 |
byte[] getReceiptData() |
エンコードされたreceiptを返します。 |
byte[] getSignedContentIdentifier() |
このreceiptの生成の原因となったメッセージの署名付きコンテンツ識別子を返します。 |
void inputContent(InputStream is) |
指定した入力ストリームからBERエンコーディングを読み取ることで、このオブジェクトを初期化します。 |
CMS receiptオブジェクトを作成する手順を次に示します。
注意:
ESSReceiptオブジェクトを作成する場合は、入力パラメータの設定をnullのままにしないでください。
クラスCMSDigestedDataContentInfoは、定数CMS.id_digestedDataで定義されるタイプid-digestedDataのオブジェクトを表します。
表4-5に、このクラスの有用なメソッドの一部を示します。
表4-5 CMSDigestedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
メッセージ・ダイジェスト値を返します。 |
|
メッセージ・ダイジェストのアルゴリズムIDを返します。 |
|
ダイジェスト済コンテンツを返します。 |
|
ダイジェスト済コンテンツのコンテンツ・タイプを返します。 |
|
このオブジェクトのバージョン番号を返します。 |
|
このオブジェクトがデタッチされているかどうかを示します。 |
|
カプセル化されたコンテンツ(つまりダイジェストされた元のオブジェクト)を設定します。 |
|
CMSDigestedDataContentInfoオブジェクトを作成する場合に、ダイジェスト対象のオブジェクトを省略する必要があるかどうかを示します。 |
CMS digested-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
デタッチされたオブジェクトを扱う場合、ダイジェストされたオブジェクトは、結果として生成されるCMS digested-data構造体には含まれません。デタッチされたオブジェクトを生成するには、writeDetached (true | false)メソッドをコールします。次に例を示します。
dig.writeDetached(true);
前述のとおり、デタッチされたCMS digested-dataオブジェクトを読み取ることはできますが、ダイジェストされた元のオブジェクトが存在しないため、ダイジェストの検証は失敗します。これを解決するためには、次のようにsetEnclosed (CMScontentInfo)メソッドをコールしてdigestedContentを設定します。
digdata.setEnclosed(CMScontentInfo object);
この後で、次のようにダイジェストの検証をします。
digdata.verify();
クラスCMSSignedDataContentInfoは、定数CMS.id_signedDataで定義されるタイプid-signedDataのオブジェクトを表します。
Oracle CMSでは、SignerIdentifierとして使用するためにIssuerAndSerialNoまたはSubjectKeyIdentifierの選択がサポートされます。ただし、PKCS #7およびS/MIMEとの相互運用性を保つためには、IssuerAndSerialNoをSignerIdentifierとして使用する必要があります。
表4-6に、このクラスの有用なメソッドの一部を示します。
表4-6 CMSSignedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
void addCertificate(X509Certificate cert) |
このsigned-dataオブジェクトに含める証明書のリストに所定の証明書を追加します。 |
void addCRL(CRL crl) |
このsigned-dataオブジェクトに含めるCRLのリストに所定のCRLを追加します。 |
void addSignature(AttributeSet authenticatedAttributes, PrivateKey signerKey, X509Certificate signerCert, AlgorithmIdentifier digestAlgID, AlgorithmIdentifier digestEncryptionAlgID, AttributeSet unauthenticatedAttributes) |
IssuerAndSerialNumber(つまりVersion1 CMSSignerInfo)をSignerIdentifierとして使用し、署名を追加します。 |
void addSignature(AttributeSet authenticatedAttributes, PrivateKey signerKey, X509Certificate signerCert, AlgorithmIdentifier digestAlgID, AlgorithmIdentifier digestEncryptionAlgID, AttributeSet unauthenticatedAttributes, boolean useSPKI64) |
SubjectKeyIdentifier(つまりVersion3 CMSSignerInfo)をSignerIdentifierとして使用し、署名を追加します。 |
void addSignerInfo(X509Certificate signerCert, CMSSignerInfo signerInfo) |
CMSSignerInfoを署名者のリストに追加します。 |
Vector getCertificates() |
このsigned-dataオブジェクトに含まれる証明書のリストを返します。 |
Vector getCRLs() |
このsigned-dataオブジェクトに含まれるCRLのリストを返します。 |
CMSContentInfo getEnclosed() |
署名付き文書を返します。 |
ASN1ObjectID getEnclosedContentType() |
署名付き文書のコンテンツ・タイプを返します。 |
CMSSignerInfo getSignerInfo(signerCert) |
証明書に対応するCMSSignerInfoを返します。 |
ASN1Integer getVersion() |
このオブジェクトのバージョン番号を返します。 |
boolean isDegenerate() |
これがデジェネレートのCMSSignedDataContentInfoオブジェクト(つまりSignerInfo構造体がない)かどうかを示します。 |
boolean isDetached() |
これがデタッチされたオブジェクトかどうかを示します。 |
boolean isExternalSignature() |
外部署名の存在をチェックします。 |
void setEnclosed(CMSContentInfo content) |
署名付きコンテンツを設定します。 |
Enumeration signers() |
このsigned-dataオブジェクトの署名を列挙の形式で返します。列挙の各要素は |
void verify(CertificateTrustPolicy trustPolicy) |
所定の信頼ポリシーに従い、このCMS signed dataオブジェクトに少なくとも1つの有効な署名が含まれるかどうかを返します。 |
void verify(CertificateTrustPolicy trustPolicy,CMSContentInfo contentInfo) |
所定の信頼ポリシーに従い、このsigned-dataオブジェクトに少なくとも1つの有効な署名が含まれるかどうかを返します。 |
void verifySignature(X509Certificate signerCert) |
このsigned-dataオブジェクトに、所定の証明書で検証される署名が含まれるかどうかを返します。 |
void verifySignature(X509Certificate signerCert, CMSContentInfo contentInfo) |
このsigned-dataオブジェクトに、所定の証明書とデータで検証される署名が含まれるかどうかを返します。 |
void writeExternalSignature(boolean createExternalSignature) |
外部署名を作成する必要があるかどうかを示します。 |
RSAおよびDSA署名アルゴリズムを使用する場合は、プロバイダがOracle CMS実装でプラガブルになることに注意してください。
CMS signed-dataオブジェクトを作成する手順を次に示します。
CMSSignedDataContentInfoのインスタンスを作成します。たとえば、CMSSignedDataContentInfoオブジェクトを作成するには、contentInfoオブジェクト(署名の対象になるデータ)を次のように渡します。
CMSSignedDataContentInfo sig = new CMSSignedDataContentInfo(contentInfo);
署名を追加します。
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate envCert = (X509Certificate)cf.generateCertificate(new FileInputStream("name1"));
PrivateKey signerKey =
...;
次のように、IssuerAndSerialNoをSignerIdentifierとして使用し、MD5ダイジェストおよびRSA署名アルゴリズムを使用して、署名を追加します。
sig.addSignature(null, signerKey, signerCert, CMS.md5, CMS.rsaEncryption, null);
次のように、64ビットSubjectKeyIdentifierをSignerIdentifierとして使用し、SHA-1ダイジェストおよびDSS署名アルゴリズムを使用して、署名を追加します。
sig.addSignature(null, signerKey, signerCert, CMS.sha_1, CMS.dsaWithSHA, null, true);
次のように、160ビットSubjectKeyIdentifierをSignerIdentifierとして使用し、SHA-1ダイジェストおよびRSA署名アルゴリズムを使用して、署名を追加します。
sig.addSignature(null, signerKey, signerCert, CMS.sha_1, CMS.rsaEncryption, null, false);
証明書とCRLを追加します。
sig.addCertificate (....) sig.addCRL (...)
CMS signed-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
sig.output(new FileOutputStream("data.p7m"));
CMS signed-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
デタッチされたオブジェクトの場合、結果として生成されるCMS signed-data構造体に署名付きオブジェクトは含まれません。デタッチされたオブジェクトを生成するには、writeExternalSignature()メソッドをコールします。
sig.writeExternalSignature(true);
「CMS signed-dataオブジェクトの読取り」で説明したとおり、デタッチされたCMS signed-dataオブジェクトを読み取ることはできますが、署名付きの元のオブジェクトが存在しないため、署名の検証は失敗します。これに対処するには、次のようにsetEnclosed(..)メソッドを最初にコールして、署名付きコンテンツを設定します。
sigdata.setEnclosed(contentInfo);
この後で、次のように署名の検証をします。
sigdata.verifySignature(signerCert);
これらは、基本的には、証明書またはCRL(あるいはその両方)が添付され、署名がないCMSSignedDataContentInfoオブジェクトです。次のように証明書またはCRL専用オブジェクトを生成します。
CMSSignedDataContentInfo sigdata = new CMSSignedDataContentInfo(new CMSDataContentInfo(new byte[0])); sigData.addCertificate (...); sigData.addCRL( ...); sigData.output(..);
証明書またはCRL専用signed-dataオブジェクトの読取りは、「CMS signed-dataオブジェクトの読取り」と同様に行うことができます。
クラスCMSEncryptedDataContentInfoは、定数CMS.id_encryptedDataで定義されるタイプid-encryptedDataのオブジェクトを表します。
表4-7に、このクラスの有用なメソッドの一部を示します。
表4-7 CMSEncryptedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
AlgorithmIdentifier getContentEncryptionAlgID() |
コンテンツ暗号化アルゴリズムを返します。 |
CMSContentInfo getEnclosed(SecreKey decryptionKey) |
復号化されたコンテンツを返します。 |
ASN1ObjectID getEnclosedContentType() |
暗号化されたコンテンツのコンテンツ・タイプを返します。 |
byte[] getEncryptedContent() |
暗号化されたコンテンツを返します。 |
AttributeSet getUnprotectedAttributes() |
保護されていない属性のセットを返します。 |
ASN1Integer getVersion() |
バージョン番号を返します。 |
boolean isDetached() |
これがデタッチされたCMSオブジェクトかどうかを示します。 |
void setUnprotectedAttributes (oracle.security.crypto.cert.AttributeSet unprotectedAttributes) |
保護されない属性を設定します。 |
void writeDetached (boolean writeDetachedObject) |
このオブジェクトの出力エンコーディングにおいて、encryptedContentをEncryptedContentInfo構造体に含めるかどうかを示します。 |
RC2、DES、Triple-DES、AESなどの暗号化操作を使用する場合は、暗号プロバイダがOracle Security Engine実装でプラガブルになることに注意してください。
encrypted-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
デタッチされたオブジェクトの場合、結果として生成されるCMS encrypted-data構造体に暗号化されたオブジェクトは含まれません。デタッチされたオブジェクトを生成するには、writeDetached(..)メソッドをコールします。
encData.writeDetached(true);
「CMS encrypted-dataオブジェクトの読取り」で説明したとおり、デタッチされたCMS encrypted-dataオブジェクトを読み取ることはできますが、暗号化された元のオブジェクトが存在しないため、コンテンツの復号化は失敗します。setEnclosed (..)メソッドをコールして、encryptedContentを設定します。
encData.setEnclosed(encryptedcontent());
この後で、次のようにコンテンツを復号化します。
encdata.getEnclosed(ContentEncryptionKey);
クラスCMSEnvelopedDataContentInfoは、定数CMS.id_envelopedDataで定義されるタイプid-envelopedDataのオブジェクトを表します。
表4-8に、このクラスの有用なメソッドの一部を示します。
表4-8 CMSEnvelopedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
void addRecipient(AlgorithmIdentifier keyEncryptionAlgID, SecretKey keyEncryptionKey, byte[] keyIdentifier, Date keyDate, ASN1Sequence otherKeyAttribute) |
鍵暗号化(ラップ)鍵交換メカニズムを使用する受信者を追加します。 |
void addRecipient(CMSRecipientInfoSpec ris) |
鍵交換メカニズム仕様を使用する受信者を追加します。 |
void addRecipient(X509Certificate recipientCert, AlgorithmIdentifier keyEncryptionAlgID) |
鍵転送(IssuerAndSerialNo)鍵交換メカニズムを使用する受信者を追加します。 |
void addRecipient(X509Certificate recipientCert, AlgorithmIdentifier keyEncryptionAlgID, boolean useSPKI64) |
鍵転送(SubjectKeyIdentifier)鍵交換メカニズムを使用する受信者を追加します。 |
AlgorithmIdentifier getContentEncryptionAlgID() |
コンテンツ暗号化アルゴリズムを返します。 |
CMSContentInfo getEnclosed(PrivateKey privateKey, X509Certificate recipientCert) |
鍵転送のRecipientInfoを使用して復号化した後に、エンクローズされたコンテンツを返します。 |
CMSContentInfo getEnclosed(SecretKey symmetricKey, byte[] keyIdentifier) |
鍵暗号化のRecipientInfoを使用して復号化した後に、エンクローズされたコンテンツを返します。 |
CMSContentInfo getEnclosed(SecretKey symmetricKey, byte[] keyIdentifier,Date keyDate) |
復号化した後にエンクローズされたコンテンツを返します。 |
ASN1ObjectID getEnclosedContentType() |
暗号化されたコンテンツのコンテンツ・タイプを返します。 |
byte[] getEncryptedContent() |
暗号化されエンクローズされたコンテンツを返します。 |
OriginatorInfo getOriginatorInfo() |
OriginatorInfoを返します |
AttributeSet getUnprotectedAttribs() |
保護されない属性を返します。 |
ASN1Integer getVersion() |
バージョン番号を返します。 |
boolean isDetached() |
暗号化されたコンテンツが存在しないかどうかを示します。 |
Enumeration recipients() |
メッセージ受信者のリストを返します。 |
void setEnclosed(byte[] encryptedContent) |
暗号化されたコンテンツを設定します。 |
void setOriginatorInfo(OriginatorInfo origInfo) |
OriginatorInfoを設定します |
void setUnprotectedAttribs (oracle.security.crypto.cert.AttributeSet unprotectedAttributes) |
保護されない属性を設定します。 |
void writeDetached(boolean writeDetached) |
このオブジェクトの出力エンコーディングから暗号化されたコンテンツを省略する必要があるかどうかを示します。 |
Oracle CMSでは、CMS3DESWrapおよびCMSRC2Wrapアルゴリズムがサポートされます。混在モードのラップはサポートされません。たとえば、3DESの鍵をRC2でラップすることはできません。
注意:
OtherKeyAttributeを使用すると、相互運用性の問題が発生する場合があります。
デタッチされたオブジェクトを扱う場合、結果として生成されるCMS enveloped-data構造体にエンベロープ・オブジェクトは含まれません。デタッチされたオブジェクトを生成するには、writeDetached(..)メソッドをコールします。
envdata.writeDetached(true);
「CMS enveloped-dataオブジェクトの読取り」で説明したとおり、デタッチされたenveloped-dataオブジェクトを読み取ることはできますが、元のエンベロープ・オブジェクトが存在しないため、コンテンツの復号化は失敗します。setEnclosed(..)メソッドをコールして、エンベロープ・コンテンツを設定します。
envdata.setEnclosed(env.getEncryptedContent());
この後で、次のようにコンテンツを復号化します。
envdata.getEnclosed(............);
クラスCMSAuthenticatedDataContentInfoは、定数CMS.id_ct_authDataで定義されるid-ct-authDataタイプのオブジェクトを表します。
注意:
Oracle CMSでは、HMAC-SHA1メッセージ認証コード(MAC)アルゴリズムがサポートされます。
表4-9に、このクラスの有用なメソッドの一部を示します。
表4-9 CMSAuthenticatedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
void addRecipient(AlgorithmIdentifier keyEncryptionAlgID, SecretKey keyEncryptionKey, byte[] keyIdentifier, java.util.Date keyDate, ASN1Sequence otherKeyAttribute) |
鍵ラップ鍵交換メカニズムを使用する受信者を追加します。 |
void addRecipient(CMSRecipientInfoSpec ris) |
指定した鍵交換メカニズムを使用する受信者を追加します。 |
void addRecipient(X509Certificate recipientCert, AlgorithmIdentifier keyEncryptionAlgID) |
受信者識別子としてIssuerAndSerialNoを使用した鍵転送鍵交換メカニズムを使用する受信者を追加します。 |
void addRecipient(X509Certificate recipientCert, AlgorithmIdentifier keyEncryptionAlgID, boolean useSPKI64) |
受信者識別子としてSubjectKeyIdentifierを使用した鍵転送鍵交換メカニズムを使用する受信者を追加します。 |
AttributeSet getAuthenticatedAttributes() |
認証された属性を返します。 |
AlgorithmIdentifier getDigestAlgID() |
ダイジェスト・アルゴリズムを返します。 |
CMSContentInfo getEnclosed() |
認証されたコンテンツを返します。 |
ASN1ObjectID getEnclosedContentType() |
エンクローズされたコンテンツのコンテンツ・タイプを返します。 |
byte[] getMAC() |
メッセージ認証コードを返します。 |
AlgorithmIdentifier getMACAlgID() |
認証に使用されたMACアルゴリズムを返します。 |
OriginatorInfo getOriginatorInfo() |
発信元の情報を返します。 |
AttributeSet getUnauthenticatedAttributes() |
認証されなかった属性を返します。 |
ASN1Integer getVersion() |
バージョン番号を返します。 |
boolean isDetached() |
このオブジェクトがデタッチされているかどうかを示します。 |
java.util.Enumeration recipients() |
メッセージ受信者のリストを返します。 |
void setAuthenticatedAttributes(AttributeSet authenticatedAttributes, AlgorithmIdentifier digestAlgorithm) |
認証された属性を設定します。 |
void setEnclosed(CMSContentInfo content) |
認証されたコンテンツを設定します。 |
void setOriginatorInfo(OriginatorInfo originatorInfo) |
OriginatorInfoを設定します。 |
void setUnauthenticatedAttributes(AttributeSet unauthenticatedAttributes) |
認証されなかった属性を設定します。 |
void verifyMAC(PrivateKey privateKey, X509Certificate recipientCert) |
復号化した後にエンクローズされたコンテンツを返します。 |
void verifyMAC(SecretKey symmetricKey, byte[] keyIdentifier) |
復号化した後にエンクローズされたコンテンツを返します。 |
void verifyMAC(SecretKey symmetricKey, byte[] keyIdentifier, Date keyDate) |
復号化した後にエンクローズされたコンテンツを返します。 |
void verifyMAC(SecretKey symmetricKey, byte[] keyIdentifier, Date keyDate, ASN1Sequence otherKeyAttribute) |
復号化した後にエンクローズされたコンテンツを返します。 |
void writeDetached(boolean writeDetachedObject) |
このオブジェクトの出力エンコーディングから認証されたコンテンツを省略する必要があるかどうかを示します。 |
authenticated-dataオブジェクトの使用の開始点はCMSAuthenticatedDataContentInfoクラスです。
authenticated-dataオブジェクトを作成する手順を次に示します。
オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
オブジェクトの読取りの手順は次のとおりです。
CMSContentInfoオブジェクトを別のCMSContentInfoオブジェクトでラップするには、コンストラクタを介して、初期化したCMSContentInfoオブジェクトを外側のCMSContentInfoオブジェクトに渡します。一番外側のCMSContentInfoオブジェクトのoutput(..)メソッドをコールして、ネストしたオブジェクトを生成します。
ネストしたオブジェクトの読取り方法は、事前に一番外側のコンテンツ・タイプがわかっているかどうかによって異なります。
一番外側のコンテンツ・タイプが事前にわからない場合は、次のように静的なメソッドをコールします。
CMSContentInfo.inputInstance( ... )
一番外側のコンテンツ・タイプが事前にわかっている場合は、次のように適切なコンストラクタをコールします。
new CMS***DataContentInfo( .... )
その後、getEnclosed(..)メソッドを再帰コールし、内側のオブジェクトを1つずつ抽出します。
CMS**DataContentInfoクラスにより、CMS***Streamクラスと同じ機能が提供されます。CMS**DataContentInfoクラスに対するCMS***Streamクラスの最大の利点は、1つのパスでCMSオブジェクトの作成または読取りが可能であり、すべての入力データを累積する必要がないことです。
ネストされたCMSオブジェクトの読取り時に、CMSInputStreamのかわりにCMSInputConnectorが使用されます。
表4-10に、CMS***Streamクラスのコンテンツ・タイプを示します。
表4-10 CMS***Streamクラス
| クラス | コンテンツ・タイプ |
|---|---|
CMSDigestedDataInputStream, CMSDigestedDataOutputStream |
CMS.id_digestedData |
CMSSignedDataInputStream, CMSSignedDataOutputStream |
CMS.id_signedData |
CMSEncryptedDataInputStream, CMSEncryptedDataOutputStream |
CMS.id_encryptedData |
CMSEnvelopedDataInputStream, CMSEnvelopedDataOutputStream |
CMS.id_envelopedData |
CMSAuthenticatedDataInputStream、CMSAuthenticatedDataOutputStream |
CMS.id_ct_authData |
表4-11に、CMS***Connectorクラスのコンテンツ・タイプを示します。
表4-11 CMS***Connectorクラス
| クラス | コンテンツ・タイプ |
|---|---|
CMSDigestedDataInputConnector、CMSDigestedDataOutputConnector |
CMS.id_digestedData |
CMSSignedDataInputConnector、CMSSignedDataOutputConnector |
CMS.id_signedData |
CMSEncryptedDataInputConnector、CMSEncryptedDataOutputConnector |
CMS.id_encryptedData |
CMSEnvelopedDataInputConnector、CMSEnvelopedDataOutputConnector |
CMS.id_envelopedData |
CMSAuthenticatedDataInputConnector、CMSAuthenticatedDataOutputConnector |
CMS.id_ct_authData |
オブジェクトを処理する場合、CMS***StreamクラスおよびCMS***Connectorクラスには次の制限があります。
デタッチされたCMS id-digestedDataオブジェクトのダイジェストを検証できません。
デタッチされたCMS id-signedDataオブジェクトの署名を検証できません。
デタッチされたCMS id-ct-authDataオブジェクトのMACを検証できません。
注意:
デタッチされたオブジェクトを処理する場合は、常にCMS**DataContentInfoクラスを使用してください。
CMS***OutputStreamクラスは、CMS (RFC-2630) ContentInfo構造体内でそのクラスに書き込まれるデータをラップする出力ストリーム・フィルタで、その後、そのBERエンコーディングが、基礎となる出力ストリームに書き込まれます。CMS***OutputConnectorクラスは、同様に、CMS (RFC-2630) ContentInfo構造体内でそのクラスに書き込まれるデータをラップする出力ストリーム・フィルタですが、基礎となる出力ストリームに書き込まれるのは、ContentInfo構造体のContentフィールドの8ビット値(明示的な[0]タグを省いたもの)のみです。
CMS***InputStreamクラスは、基礎となる出力ストリームからCMS (RFC 2630)ContentInfo構造体のBERエンコーディングを読み取る入力ストリーム・フィルタです。CMS***InputConnectorクラスは入力ストリーム・フィルタであり、基礎となる入力ストリームがContentInfo構造体のContentフィールドの8ビット値の開始位置(明示的な[0]タグの後)にあることを前提としています。
CMS***Connectorは、ネストしたオブジェクトの作成と読取りを行う場合に便利です。
CMS***InputStreamにはCMSオブジェクトを読み取るためのメソッドが含まれます。CMS***OutputStreamはCMSオブジェクトを出力ストリームに書き込みます。
オブジェクトを構成する手順を次に示します。
適切なコンテンツ・タイプのCMS***OutputStreamクラスを作成します。関連するすべてのパラメータはコンストラクタを介して渡されます。
ステップ1で作成したCMS***OutputStreamに、保護するデータを書き込みます。
すべてのデータを書き込んだら、ステップ1で作成したCMS***OutputStreamを閉じます。
オブジェクトを読み取る手順を次に示します。
read()およびread (byte[],...)メソッドを使用して、ステップ1で作成したCMS***InputStreamから、保護されているデータを読み取ります。1で作成したCMS***InputStreamからのデータの読取りが終了したら、terminate()を呼び出します。これで、オブジェクトの読取りが完了します。getData()メソッドから返されるデータは、CMS***OutputStreamまたはCMS***OutputConnectorに書き込むことができます。
getReceiptData()メソッドから返されるエンコード済receiptは、CMS***OutputStreamまたはCMS***OutputConnectorに書き込むことができます。
次のように入力ストリームからESSReceiptデータを読み取ります。
byte[] rcptData = in.read(...); ESSReceipt er = new ESSReceipt(); er.inputContent(rcptData);
デタッチされたdigested-dataオブジェクトのダイジェストを検証することはできません。CMSDigestedDataOutputStreamコンストラクタのブール値のパラメータwriteEContentInfoをfalseに設定すると、デタッチされたdigested-dataオブジェクトを作成できるようになります。
デタッチされたsigned-dataオブジェクトの署名を検証することはできません。
CMSSignerInfoSpecクラスには署名者固有の情報が格納されます。追加する署名ごとに、対応するCMSSignerInfoSpecオブジェクトを作成して、コンストラクタに渡す必要があります。
CMSSignedDataOutputStreamコンストラクタのブール値のパラメータcreateExternalSignaturesをtrueに設定すると、デタッチされたsigned-dataオブジェクトすなわち外部署名を作成できるようになります。
証明書またはCRL専用オブジェクトを作成する場合は、署名者情報をCMSDSignedDataOutputStreamコンストラクタに渡さないでください。
CMSEncryptedDataOutputStreamコンストラクタのブール値のパラメータwriteEncryptedOutputをfalseに設定すると、デタッチされたencrypted-dataオブジェクトを作成できるようになります。
CMSRecipientInfoSpecクラスには受信者固有の情報が格納されます。追加する受信者ごとに、対応するCMSRecipientInfoSpecオブジェクトを作成して、コンストラクタに渡す必要があります。
CMSEnvelopedDataOutputStreamコンストラクタのブール値のパラメータwriteContentをfalseに設定すると、デタッチされたenveloped-dataオブジェクトを作成できるようになります。
受信者は交換メカニズムにより分類されます。次の表で、様々なメカニズムを定義します。
| 交換メカニズム | 使用方法 |
|---|---|
鍵転送鍵交換メカニズム |
|
鍵合意鍵交換メカニズム |
このメカニズムは現在サポートされていません。 |
鍵暗号化(ラップ)鍵交換メカニズム |
|
CMS***OutputConnectorを使用して、ネストしたオブジェクトを作成します。
次のコードを使用して、signed-data、enveloped-data、digested-dataおよびencrypted-dataを作成し、ファイルnested.p7mに書き込みます。
// nested.p7m <--- FileOutputStream <--- CMSSignedDataOutputConnector
// <--- CMSEnvelopedDataOutputConnector <---
// <---- CMSDigestedDataOutputConnector <---
// <---- CMSEncryptedDataOutputConnector <---
// <---- write the data (byte[] data)
FileOutputStream fos = new FileOutputStream("nested.p7m");
CMSSignedDataOutputConnector conn1 =
new CMSSignedDataOutputConnector(fos, .....);
CMSEnvelopedDataOutputConnector conn2 =
new CMSEnvelopedDataOutputConnector(conn1, ...);
CMSDigestedDataOutputConnector conn3 =
new CMSDigestedDataOutputConnector(conn2, ...);
CMSEncryptedDataOutputConnector conn4 =
new CMSEncryptedDataOutputConnector(conn3, ...);
OutputStream os = conn4.getOutputStream();
os.write(data);
os.close();
次のコードを使用して、ファイルnested.p7mに格納されているsigned-data、enveloped-data、digested-dataおよびencrypted-dataを読み取ります。
// nested.p7m ---> FileInputStream ---> CMSSignedDataInputConnector -
// ---> CMSEnvelopedDataInputConnector ---
// -----> CMSDigestedDataInputConnector ---
// ----> CMSEncryptedDataInputConnector ---
// ---> read the data (byte[] data)
FileInputStream fos = new FileInputStream("nested.p7m");
CMSSignedDataInputConnector conn1 =
new CMSSignedDataInputConnector(fos, .....);
CMSEnvelopedDataInputConnector conn2 =
new CMSEnvelopedDataInputConnector(conn1, ...);
CMSDigestedDataInputConnector conn3 =
new CMSDigestedDataInputConnector(conn2, ...);
CMSEncryptedDataInputConnector conn4 =
new CMSEncryptedDataInputConnector(conn3, ...);
InputStream is = conn4.getInputStream();
is.read(data);