| Oracle® Fusion Middleware Oracle Security Developer Toolsによるセキュアなアプリケーションの開発 11gリリース1 (11.1.1) B61386-04 |
|
![]() 前 |
![]() 次 |
この章では、Oracle CMSの主要な機能と利点、Oracle CMSの設定および使用の方法について説明します。
この章に含まれる内容は次のとおりです。
Oracle CMS SDKは、CMSオブジェクトの読取りと書込みのためのツール、サンプル・プログラム、および安全なメッセージ・エンベロープを開発するためのサポート・ツールなど、豊富なツールを含むPure Java APIです。
Oracle CMSでは、RFC 2630に指定されているIETF暗号メッセージ構文が実装されます。この構文は、メッセージのデジタル署名、ダイジェスト、認証および暗号化に使用されます。
暗号メッセージ構文は、RFC 2315[PKCS#7]に指定されているように、PKCS #7バージョン1.5から導出されています。
Oracle CMSでは、表5-1に示すように、RFC 2630に指定されているすべてのコンテンツ・タイプがサポートされます。
表5-1 Oracle CMSでサポートされるコンテンツ・タイプ
| タイプ | ID |
|---|---|
|
data |
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コンテンツ・タイプに対する拡張セキュリティ・サービスがサポートされます。
| タイプ | ID |
|---|---|
| receipt | 1.2.840.113549.1.9.16.1.2 |
次の、RFC 3161に対応するIETF PKIXタイムスタンプ・プロトコルのコンテンツ・タイプもサポートされます。
| タイプ | ID |
|---|---|
| TSTInfo | 1.2.840.113549.1.9.16.1.4 |
|
注意: Oracle CMSでは、これまでに説明したコンテンツ・タイプ以外は処理されません。 |
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の環境を設定する方法について説明します。次の項目が含まれます。
CLASSPATH環境変数には、必要なjarファイルおよびclassファイルすべてのフルパスとファイル名を指定してください。次の項目をCLASSPATHに指定します。
osdt_core.jarファイル
osdt_cert.jarファイル
osdt_cms.jarファイル
WindowsでCLASSPATHを設定する手順を次に示します。
Windowsの「コントロール パネル」で「システム」を選択します。
「システムのプロパティ」ダイアログで「詳細設定」タブを選択します。
「環境変数」をクリックします。
ユーザー環境変数のセクションで「新規」をクリックし、CLASSPATH環境変数をユーザー・プロファイルに追加します。CLASSPATH環境変数がすでに存在している場合は、選択して「編集」をクリックします。
必要なjarファイルおよびclassファイルすべてのフルパスとファイル名をCLASSPATHに追加します。
たとえば、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;
「OK」をクリックします。
UNIXでCLASSPATHを設定するには、必要なjarファイルおよびclassファイルすべてのフルパスとファイル名を含むようにCLASSPATH環境変数を設定します。次に例を示します。
setenv 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.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オブジェクトに存在しません。
表5-2に、CMS***ContentInfoクラスを構成するクラスを示します。
表5-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オブジェクトを表す抽象クラスです。表5-2に、CMSContentInfoのサブクラスを示しています。
この抽象クラスの有用なメソッドの一部を、表5-3に示します。
表5-3 CMSContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
contentTypeName |
オブジェクトのコンテンツ・タイプを文字列として返します。 |
|
getContentType() |
オブジェクトのコンテンツ・タイプをオブジェクト識別子(OID)として返します。 |
|
input(java.io.InputStream is) |
指定した入力ストリームからBERエンコーディングを読み取ることで、このオブジェクトを初期化します。 |
|
inputInstance(java.io.InputStream is) |
指定した入力ストリームからBERエンコーディングを読み取ることで、新しいCMSContentInfoオブジェクトを作成します。 |
|
isDegenerate() |
オブジェクトがデジェネレートかどうかを示します。 |
|
isDetached() |
オブジェクトがデタッチされているかどうかを示します。 |
|
output(java.io.OutputStream os) |
オブジェクトのエンコーディングを所定の出力ストリームに書き込みます。 |
CMSオブジェクトを構成する手順を次に示します。
指定されたコンテンツ・タイプのオブジェクトを作成します。
オブジェクトを初期化します。
output(..)メソッドをコールして、オブジェクト・エンコーディングを書き込みます。
既存のCMSContentInfoを読み取る際、事前に具体タイプがわからない場合には、inputInstance()を使用します。新しいオブジェクトを作成するには、作業している具体サブクラスのいずれかのコンストラクタを使用します。具体タイプのいずれかがわかっていて読み取るには、引数なしのコンストラクタを使用し、input()メソッドを呼び出します。
クラス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オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
FileInputStreamを使用してファイルとの接続を開きます。
ファイルdata.p7mに格納されているオブジェクトのコンテンツ・タイプがid-dataであるとわかっている場合は、次のようにします。
CMSDataContentInfo exdata =
new CMSDataContentInfo(new FileInputStream("data.p7m"));
ただし、事前にコンテンツ・タイプがわからない場合は、読取りの前にタイプを調べます。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof CMSDataContentInfo)
{
CMSDataContentInfo exdata = (CMSDataContentInfo) cmsdata;
// .....
}
次のようにCMS dataオブジェクトに格納されている情報にアクセスします。
byte[] docBytes = exdata.getData();
クラスESSReceiptは、定数CMS.id_ct_receiptで定義されるid-ct-receiptタイプのオブジェクトを表し、RFC 2634のreceiptを指します。
表5-4に、このクラスの有用なメソッドの一部を示します。
表5-4 ESSReceiptの有用なメソッド
| メソッド | 説明 |
|---|---|
|
byte[] getOriginatorSignatureValue() |
このreceiptの生成の原因となったメッセージの署名値を返します。 |
|
ASN1ObjectID getReceiptContentType() |
このreceiptの生成の原因となったメッセージのコンテンツ・タイプを返します。 |
|
byte[] getReceiptData() |
エンコードされたreceiptを返します。 |
|
byte[] getSignedContentIdentifier() |
このreceiptの生成の原因となったメッセージの署名付きコンテンツ識別子を返します。 |
|
void inputContent(InputStream is) |
指定した入力ストリームからBERエンコーディングを読み取ることで、このオブジェクトを初期化します。 |
CMS receiptオブジェクトを作成する手順を次に示します。
コンテンツ・タイプの識別子、署名付きコンテンツ識別子を含むバイト配列、および発信者の署名値を含むバイト配列をとるコンストラクタを使用して、次のようにESSReceiptのインスタンスを作成します。
ESSReceipt rcpt =
new ESSReceipt(contentType, signedContentIdentifier,
originatorSignatureValue);
receiptオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
rcpt.output(new FileOutputStream("data.p7m"));
|
注意: ESSReceiptオブジェクトを作成する場合は、入力パラメータの設定をnullのままにしないでください。 |
receiptオブジェクトを読み取る手順を次に示します。
FileInputStreamを使用してファイルとの接続を開きます。
ファイルdata.p7mに格納されているオブジェクトのコンテンツ・タイプがid-ct-receiptであるとわかっている場合は、次のようにします。
ESSReceipt rcptdata = new ESSReceipt(new FileInputStream("data.p7m"));
コンテンツ・タイプがわからない場合は、次のようにします。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof ESSReceipt)
{
ESSReceipt rcptdata = (ESSReceipt) cmsdata;
// .....
}
receiptオブジェクトに格納されている情報に次のようにアクセスします。
ASASN1ObjectID contentType = rcptdata.getReceiptContentType(); byte[] sciBytes = rcptdata.getSignedContentIdentifier() byte[] osvBytes = rcptdata.getOriginatorSignatureValue();
クラスCMSDigestedDataContentInfoは、定数CMS.id_digestedDataで定義されるタイプid-digestedDataのオブジェクトを表します。
表5-5に、このクラスの有用なメソッドの一部を示します。
表5-5 CMSDigestedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
|
メッセージ・ダイジェスト値を返します。 |
|
|
メッセージ・ダイジェストのアルゴリズムIDを返します。 |
|
|
ダイジェスト済コンテンツを返します。 |
|
|
ダイジェスト済コンテンツのコンテンツ・タイプを返します。 |
|
|
このオブジェクトのバージョン番号を返します。 |
|
|
このオブジェクトがデタッチされているかどうかを示します。 |
|
|
カプセル化されたコンテンツ(つまりダイジェストされた元のオブジェクト)を設定します。 |
|
|
CMSDigestedDataContentInfoオブジェクトを作成する場合に、ダイジェスト対象のオブジェクトを省略する必要があるかどうかを示します。 |
CMS digested-dataオブジェクトを作成する手順を次に示します。
ダイジェスト対象のオブジェクトとダイジェスト・アルゴリズム識別子をとるコンストラクタを使用して、CMSDigestedDataContentInfoのインスタンスを作成します。たとえば、contentInfoがCMSDataContentInfoオブジェクト、MD5がダイジェスト・アルゴリズムの場合は、次のようになります。
CMSDigestedDataContentInfo dig =
new CMSDigestedDataContentInfo(contentInfo, CMS.md5);
CMS digested-dataオブジェクトをdata.p7mというファイルに書き込みます。
dig.output(new FileOutputStream("data.p7m"));
CMS digested-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
FileInputStreamを使用してファイルdata.p7mとの接続を開きます。
ファイルに格納されているオブジェクトのコンテンツ・タイプがid-digestedDataであるとわかっている場合は、次のように接続を開きます。
CMSDigestedDataContentInfo digdata =
new CMSDigestedDataContentInfo(new FileInputStream("data.p7m"));
事前にコンテンツ・タイプがわからない場合は、次のように接続を開きます。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof CMSDigestedDataContentInfo)
{
CMSDigestedDataContentInfo digdata =
(CMSDigestedDataContentInfo) cmsdata;
// .....
}
次のようにCMS digested-dataオブジェクトに格納されている情報にアクセスします。
int version = digdata.getVersionNumber().intValue();
AlgorithmIdentifier digestAlgID = digdata.getDigestAlgID();
byte[] digestValue = digdata.getDigest();
CMSContentInfo digContentInfo = digData.getEnclosed()
if (digData.getEnclosedContentType().equals(CMS.id_data))
CMSDataContentInfo contentInfo = (CMSDataContentInfo)digContentInfo;
保護されるデータの整合性を確認するために、次のようにダイジェストを検証します。
digData.verify();
デタッチされたオブジェクトを扱う場合、ダイジェストされたオブジェクトは、結果として生成される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として使用する必要があります。
表5-6に、このクラスの有用なメソッドの一部を示します。
表5-6 CMSSignedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
void addCertificate(X509Certificate cert) |
このsigned-dataオブジェクトに含める証明書のリストに所定の証明書を追加します。 |
|
void addCRL(CRL crl) |
このsigned-dataオブジェクトに含めるCRLのリストに所定のCRLを追加します。 |
|
void addSignature(AttributeSet authenticatedAttributes, |
IssuerAndSerialNumber(つまりVersion1 CMSSignerInfo)をSignerIdentifierとして使用し、署名を追加します。 |
|
void addSignature(AttributeSet authenticatedAttributes, |
SubjectKeyIdentifier(つまりVersion3 CMSSignerInfo)をSignerIdentifierとして使用し、署名を追加します。 |
|
void addSignerInfo(X509Certificate signerCert, |
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 |
所定の信頼ポリシーに従い、このsigned-dataオブジェクトに少なくとも1つの有効な署名が含まれるかどうかを返します。 |
|
void verifySignature(X509Certificate signerCert) |
このsigned-dataオブジェクトに、所定の証明書で検証される署名が含まれるかどうかを返します。 |
|
void verifySignature(X509Certificate signerCert, |
この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オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
FileInputStreamを使用してファイルdata.p7mとの接続を開きます。
ファイルに格納されているオブジェクトのコンテンツ・タイプがid-signedDataであるとわかっている場合は、次のようにします。
CMSSignedDataContentInfo sigdata =
new CMSSignedDataContentInfo(new FileInputStream("data.p7m"));
事前にコンテンツ・タイプがわからない場合は、次のようにします。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof CMSSignedDataContentInfo)
{
CMSSignedDataContentInfo sigdata =
(CMSSignedDataContentInfo) cmsdata;
// .....
}
次のようにCMS signed-dataオブジェクトに格納されている情報にアクセスします。
int version = sigdata.getVersion().intValue();
CMSContentInfo sigContentInfo = sigData.getEnclosed()
Vector certs = sigdata.getCertificates();
Vector crls = sigData.getCRLs();
Enumeration e = sigData.signers();
CMSContentInfo sigContentInfo = sigData.getEnclosed();
if (sigData.getEnclosedContentType().equals(CMS.id_data))
CMSDataContentInfo contentInfo = (CMSDataContentInfo)sigContentInfo;
署名者の公開鍵証明書を使用して署名を検証します。
sigData.verifySignature(signerCert);
次のように署名者の詳細を取得します。
CMSSignerInfo sigInfo = sigdata.getSignerInfo(signerCert); byte[] signatureValue = sigInfo.getEncryptedDigest(); AlgorithmIdentifier digest = sigInfo.getDigestAlgID(); AlgorithmIdentifier signature = sigInfo.getDigestEncryptionAlgID(); AttributeSet signedAttributes = sigInfo.getAuthenticatedAttributes(); AttributeSet unsignedAttributes = sigInfo.getUnauthenticatedAttributes();
デタッチ・オブジェクトの場合、結果として生成される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のオブジェクトを表します。
表5-7に、このクラスの有用なメソッドの一部を示します。
表5-7 CMSEncryptedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
AlgorithmIdentifier |
コンテンツ暗号化アルゴリズムを返します。 |
|
CMSContentInfo |
復号化されたコンテンツを返します。 |
|
ASN1ObjectID |
暗号化されたコンテンツのコンテンツ・タイプを返します。 |
|
byte[] getEncryptedContent() |
暗号化されたコンテンツを返します。 |
|
AttributeSet |
保護されていない属性のセットを返します。 |
|
ASN1Integer getVersion() |
バージョン番号を返します。 |
|
boolean isDetached() |
これがデタッチされたCMSオブジェクトかどうかを示します。 |
|
void setUnprotectedAttributes |
保護されない属性を設定します。 |
|
void writeDetached |
このオブジェクトの出力エンコーディングにおいて、encryptedContentをEncryptedContentInfo構造体に含めるかどうかを示します。 |
RC2、DES、Triple-DES、AESなどの暗号化操作を使用する場合は、暗号プロバイダがOracle Security Engine実装でプラガブルになることに注意してください。
次のようにencrypted-dataオブジェクトを作成します。
CMSEncryptedDataContentInfoのインスタンスを作成します。たとえば、contentInfoがCMSDataContentInfoオブジェクト、暗号がCBCモードのTriple-DESの場合は、次のようになります。
SecretKey contentEncryptionKey = KeyGenerator.getInstance("DESede").generateKey();
CMSEncryptedDataContentInfo enc =
new CMSEncryptedDataContentInfo(contentInfo, contentEncryptionKey,
CMS.des_ede3_cbc);
encrypted-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
enc.output(new FileOutputStream("data.p7m"));
encrypted-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
FileInputStreamを使用してファイルdata.p7mとの接続を開きます。
ファイルdata.p7mに格納されているオブジェクトのコンテンツ・タイプがid-encryptedDataであるとわかっている場合は、次のようにします。
CMSEncryptedDataContentInfo encdata =
new CMSEncryptedDataContentInfo(new FileInputStream("data.p7m"));
事前にコンテンツ・タイプがわからない場合は、次のようにします。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof CMSEncryptedDataContentInfo)
{
CMSEncryptedDataContentInfo encdata =
(CMSEncryptedDataContentInfo) cmsdata;
// .....
}
次のようにCMS encrypted-dataオブジェクトに格納されている情報にアクセスします。
int version = encdata.getVersion().intValue();
AlgorithmIdentifier encAlgID = encdata.getContentEncryptionAlgID();
byte[] encValue = encdata.getEncryptedContent();
CMSContentInfo encContentInfo =
encdata.getEnclosed(ContentEncryptionKey); //Decrypt the Content
if (encData.getEnclosedContentType().equals(CMS.id_data))
CMSDataContentInfo contentInfo = (CMSDataContentInfo)encContentInfo;
デタッチされたオブジェクトの場合、結果として生成される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のオブジェクトを表します。
表5-8に、このクラスの有用なメソッドの一部を示します。
表5-8 CMSEnvelopedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
void addRecipient(AlgorithmIdentifier keyEncryptionAlgID, |
鍵暗号化(ラップ)鍵交換メカニズムを使用する受信者を追加します。 |
|
void addRecipient(CMSRecipientInfoSpec ris) |
鍵交換メカニズム仕様を使用する受信者を追加します。 |
|
void addRecipient(X509Certificate recipientCert, |
鍵転送(IssuerAndSerialNo)鍵交換メカニズムを使用する受信者を追加します。 |
|
void addRecipient(X509Certificate recipientCert, AlgorithmIdentifier |
鍵転送(SubjectKeyIdentifier)鍵交換メカニズムを使用する受信者を追加します。 |
|
AlgorithmIdentifier getContentEncryptionAlgID() |
コンテンツ暗号化アルゴリズムを返します。 |
|
CMSContentInfo getEnclosed(PrivateKey privateKey, |
鍵転送のRecipientInfoを使用して復号化した後に、エンクローズされたコンテンツを返します。 |
|
CMSContentInfo getEnclosed(SecretKey symmetricKey, |
鍵暗号化のRecipientInfoを使用して復号化した後に、エンクローズされたコンテンツを返します。 |
|
CMSContentInfo getEnclosed(SecretKey symmetricKey, |
復号化した後にエンクローズされたコンテンツを返します。 |
|
ASN1ObjectID getEnclosedContentType() |
暗号化されたコンテンツのコンテンツ・タイプを返します。 |
|
byte[] getEncryptedContent() |
暗号化されエンクローズされたコンテンツを返します。 |
|
OriginatorInfo getOriginatorInfo() |
OriginatorInfoを返します。 |
|
AttributeSet getUnprotectedAttribs() |
保護されない属性を返します。 |
|
ASN1Integer getVersion() |
バージョン番号を返します。 |
|
boolean isDetached() |
暗号化されたコンテンツが存在しないかどうかを示します。 |
|
Enumeration recipients() |
メッセージ受信者のリストを返します。 |
|
void setEnclosed(byte[] encryptedContent) |
暗号化されたコンテンツを設定します。 |
|
void setOriginatorInfo(OriginatorInfo |
OriginatorInfoを設定します。 |
|
void |
保護されない属性を設定します。 |
|
void writeDetached(boolean writeDetached) |
このオブジェクトの出力エンコーディングから暗号化されたコンテンツを省略する必要があるかどうかを示します。 |
enveloped-dataオブジェクトを作成する手順を次に示します。
CMSEnvelopedDataContentInfoのインスタンスを作成します。たとえば、contentInfoがCMSDataContentInfoオブジェクト、暗号がCBCモードのTriple-DESの場合は、次のようになります。
CMSEnvelopedDataContentInfo env =
new CMSEnvelopedDataContentInfo(contentInfo, CMS.des_ede3_cbc);
受信者の鍵管理方法を考慮して、受信者を追加します。
受信者が鍵暗号化(ラップ)鍵管理メカニズムを使用する場合:
env.addRecipient(keyEncryptionAlgID, keyEncryptionKey,
keyIdentifier, keyDate, otherKeyAttribute);
受信者の鍵交換メカニズムがCMSRecipientInfoSpecオブジェクトを使用して指定された場合:
env.addRecipient(ris)
受信者が鍵転送(IssuerAndSerialNo受信者識別子)鍵管理メカニズムを使用する場合:
env.addRecipient(recipientCert, CMS.rsaEncryption);
受信者が鍵転送(64ビットSubjectKeyIdentifier受信者識別子)鍵管理メカニズムを使用する場合:
env.addRecipient(recipientCert, CMS.rsaEncryption, true)
受信者が鍵転送(160ビットSubjectKeyIdentifier受信者識別子)鍵管理メカニズムを使用する場合:
env.addRecipient(recipientCert, CMS.rsaEncryption, false)
オプションの引数を設定します。
env.setOriginatorInfo(originatorInfo); env.setUnprotectedAttribs(unprotectedAttributes);
CMS enveloped-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
enc.output(new FileOutputStream("data.p7m"));
オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
FileInputStreamを使用してファイルdata.p7mとの接続を開きます。ファイルに格納されているオブジェクトのコンテンツ・タイプがid-envelopedDataであるとわかっている場合は、次のように接続を開きます。
CMSEnvelopedDataContentInfo envdata =
new CMSEnvelopedDataContentInfo(new FileInputStream("data.p7m"));
事前にコンテンツ・タイプがわからない場合は、次のように接続を開きます。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof CMSEnvelopedDataContentInfo)
{
CMSEnvelopedDataContentInfo envdata =
(CMSEnvelopedDataContentInfo) cmsdata;
//
.....
}
次のようにenveloped-dataオブジェクトに格納されている情報にアクセスします。
int version = envdata.getVersion().intValue(); AlgorithmIdentifier encAlgID = envdata.getContentEncryptionAlgID(); ASN1ObjectID contentType = envdata.getEnclosedContentType(); byte[] encryptedContent = envdata.getEncryptedContent(); OriginatorInfo origInfo = envdata.getOriginatorInfo(); AttributeSet unprotected = envdata.getUnprotectedAttribs();
次のように、受信者の情報に応じてコンテンツを復号化します。
CMSContentInfo envContentInfo =
env.getEnclosed(privateKey, recipientCert);
または
CMSContentInfo envContentInfo =
env.getEnclosed(symmetricKey, keyIdentifier);
または
CMSContentInfo envContentInfo =
env.getEnclosed(symmetricKey, keyIdentifier, keyDate)
if (envContentInfo instanceof CMSDataContentInfo)
{
CMSDataContentInfo contentInfo = (CMSDataContentInfo) envContentInfo;
// ...
}
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タイプのオブジェクトを表します。
表5-9に、このクラスの有用なメソッドの一部を示します。
表5-9 CMSAuthenticatedDataContentInfoの有用なメソッド
| メソッド | 説明 |
|---|---|
|
void addRecipient(AlgorithmIdentifier keyEncryptionAlgID, |
鍵ラップ鍵交換メカニズムを使用する受信者を追加します。 |
|
void addRecipient(CMSRecipientInfoSpec ris) |
指定した鍵交換メカニズムを使用する受信者を追加します。 |
|
void addRecipient(X509Certificate recipientCert, |
受信者識別子としてIssuerAndSerialNoを使用した鍵転送鍵交換メカニズムを使用する受信者を追加します。 |
|
void addRecipient(X509Certificate recipientCert, |
受信者識別子として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, |
認証された属性を設定します。 |
|
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, |
復号化した後にエンクローズされたコンテンツを返します。 |
|
void verifyMAC(SecretKey symmetricKey, byte[] keyIdentifier, |
復号化した後にエンクローズされたコンテンツを返します。 |
|
void writeDetached(boolean writeDetachedObject) |
このオブジェクトの出力エンコーディングから認証されたコンテンツを省略する必要があるかどうかを示します。 |
authenticated-dataオブジェクトを作成する手順を次に示します。
CMSAuthenticatedDataContentInfoのインスタンスを作成します。次の例では、contentInfoがCMSDataContentInfoオブジェクト、鍵がTriple-DES HMAC、アルゴリズムがHMAC-SHA1になります。
SecretKey contentEncryptionKey =
KeyGenerator.getInstance("DESede").generateKey();
CMSAuthenticatedDataContentInfo auth =
new CMSAuthenticatedDataContentInfo(contentInfo,
contentEncryptionKey, CMS.hmac_SHA_1);
受信者の鍵管理方法を考慮して、受信者を追加します。
受信者が鍵暗号化(ラップ)鍵管理メカニズムを使用する場合:
auth.addRecipient(keyEncryptionAlgID, keyEncryptionKey, keyIdentifier,
keyDate, otherKeyAttribute);
受信者の鍵交換メカニズムがCMSRecipientInfoSpecオブジェクトを使用して指定された場合:
auth.addRecipient(ris)
受信者が鍵転送(IssuerAndSerialNo受信者識別子)鍵管理メカニズムを使用する場合:
auth.addRecipient(recipientCert, CMS.rsaEncryption);
受信者が鍵転送(64ビットSubjectKeyIdentifier受信者識別子)鍵管理メカニズムを使用する場合:
auth.addRecipient(recipientCert, CMS.rsaEncryption, true)
受信者が鍵転送(160ビットSubjectKeyIdentifier受信者識別子)鍵管理メカニズムを使用する場合:
auth.addRecipient(recipientCert, CMS.rsaEncryption, false)
オプションの引数を設定します。
auth.setAuthenticatedAttributes(authenticatedAttributes, CMS.md5); auth.setOriginatorInfo(originatorInfo); auth.setUnauthenticatedAttributes(unauthenticatedAttributes);
CMS authenticated-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
auth.output(new FileOutputStream("data.p7m"));
オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。
FileInputStreamを使用してファイルdata.p7mとの接続を開きます。ファイルに格納されているオブジェクトのコンテンツ・タイプがid-ct-authDataであるとわかっている場合は、次のようにします。
CMSAuthenticatedDataContentInfo authdata =
new CMSAuthenticatedDataContentInfo(new FileInputStream("data.p7m"));
事前にコンテンツ・タイプがわからない場合は、次のようにします。
CMSContentInfo cmsdata =
CMSContentInfo.inputInstance(new FileInputStream("data.p7m"));
if (cmsdata instanceof CMSAuthenticatedDataContentInfo)
{
CMSAuthenticatedDataContentInfo authdata =
(CMSAuthenticatedDataContentInfo) cmsdata;
// .....
}
次のようにCMS authenticated-dataオブジェクトに格納されている情報にアクセスします。
int version = authdata.getVersion().intValue();
AlgorithmIdentifier macAlgID = authdata.getMACAlgID();
byte[] macValue = authdata.getMAC();
CMSContentInfo authContentInfo = authdata.getEnclosed();
if (authData.getEnclosedContentType().equals(CMS.id_data))
CMSDataContentInfo contentInfo = (CMSDataContentInfo)authContentInfo;
次のように、受信者の情報に応じてMACを検証します。
authdata.verifyMAC(recipientPrivateKey, recipientCert);
または
authdata.verifyMAC(symmetricKey, keyIdentifier)
または
authdata.verifyMAC(symmetricKey, keyIdentifier, keyDate)
または
authdata.verifyMAC(symmetricKey, keyIdentifier, keyDate,
otherKeyAttribute)
CMSContentInfoオブジェクトを別のCMSContentInfoオブジェクトでラップするには、コンストラクタを介して、初期化したCMSContentInfoオブジェクトを外側のCMSContentInfoオブジェクトに渡します。一番外側のCMSContentInfoオブジェクトのoutput(..)メソッドをコールして、ネストしたオブジェクトを生成します。
ネストしたオブジェクトの読取り方法は、事前に一番外側のコンテンツ・タイプがわかっているかどうかによって異なります。
一番外側のコンテンツ・タイプが事前にわからない場合は、次のように静的なメソッドをコールします。
CMSContentInfo.inputInstance( ... )
一番外側のコンテンツ・タイプが事前にわかっている場合は、次のように適切なコンストラクタをコールします。
new CMS***DataContentInfo( .... )
その後、getEnclosed(..)メソッドを再帰コールし、内側のオブジェクトを1つずつ抽出します。
CMS**DataContentInfoクラスにより、CMS***Streamクラスと同じ機能が提供されます。CMS**DataContentInfoクラスに対するCMS***Streamクラスの最大の利点は、1つのパスでCMSオブジェクトの作成または読取りが可能であり、必要なすべての情報を累積する必要がないことです。
表5-10に、CMS***Streamクラスのコンテンツ・タイプを示します。
表5-10 CMS***Streamクラス
| クラス | コンテンツ・タイプ |
|---|---|
|
CMSDigestedDataInputStream, |
CMS.id_digestedData |
|
CMSSignedDataInputStream, |
CMS.id_signedData |
|
CMSEncryptedDataInputStream, |
CMS.id_encryptedData |
|
CMSEnvelopedDataInputStream, |
CMS.id_envelopedData |
|
CMSAuthenticatedDataInputStream, |
CMS.id_ct_authData |
表5-11に、CMS***Connectorクラスのコンテンツ・タイプを示します。
表5-11 CMS***Connectorクラス
| クラス | コンテンツ・タイプ |
|---|---|
|
CMSDigestedDataInputConnector, |
CMS.id_digestedData |
|
CMSSignedDataInputConnector, |
CMS.id_signedData |
|
CMSEncryptedDataInputConnector, |
CMS.id_encryptedData |
|
CMSEnvelopedDataInputConnector, |
CMS.id_envelopedData |
|
CMSAuthenticatedDataInputConnector, |
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***OutputStreamクラスを作成します。関連するすべてのパラメータはコンストラクタを介して渡されます。
ステップ1で作成したCMS***OutputStreamに、保護するデータを書き込みます。
すべてのデータを書き込んだら、ステップ1で作成したCMS***OutputStreamを閉じます。
オブジェクトを読み取る手順を次に示します。
基礎となる入力ストリームをコンストラクタを介して渡し、適切なコンテンツ・タイプのCMS***InputStreamクラスを作成します。
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オブジェクトを作成できるようになります。
鍵転送鍵交換メカニズム
CMSKeyTransRecipientInfoSpecクラスを使用して、鍵転送鍵管理メカニズムを使用する受信者情報を格納します。
鍵合意鍵交換メカニズム
このメカニズムは現在サポートされていません。
鍵暗号化(ラップ)鍵交換メカニズム
CMSKEKRecipientInfoSpecクラスを使用して、鍵ラップ鍵管理メカニズムを使用する受信者情報を格納します。
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);