ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Security Developer Toolsリファレンス
11gリリース1(11.1.1)
B61386-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

5 Oracle CMS

この章では、Oracle CMSの主要な機能と利点、Oracle CMSの設定および使用の方法について説明します。

この章に含まれる内容は次のとおりです。

5.1 Oracle CMSの機能と利点

Oracle CMS SDKは、CMSオブジェクトの読取りと書込みのためのツール、サンプル・プログラム、および安全なメッセージ・エンベロープを開発するためのサポート・ツールなど、豊富なツールを含むPure Java APIです。

Oracle CMSでは、RFC 2630に指定されているIETF暗号メッセージ構文が実装されます。この構文は、メッセージのデジタル署名、ダイジェスト、認証および暗号化に使用されます。

暗号メッセージ構文は、RFC 2315[PKCS#7]に指定されているように、PKCS #7バージョン1.5から導出されています。


関連項目:

この仕様へのリンクは、付録A「リファレンス」を参照してください。

5.1.1 コンテンツ・タイプ

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

このドキュメントへのリンクは、付録A「リファレンス」を参照してください。

次の、RFC 3161に対応するIETF PKIXタイムスタンプ・プロトコルのコンテンツ・タイプもサポートされます。

タイプ ID
TSTInfo 1.2.840.113549.1.9.16.1.4


注意:

Oracle CMSでは、これまでに説明したコンテンツ・タイプ以外は処理されません。

5.1.2 Oracle CMS実装とRFCの違い

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実装との相互運用性が必要な場合は、これらの違いに注意してください。

5.2 Oracle CMSの環境設定

Oracleセキュリティ開発ツールは、Oracle Application ServerとともにORACLE_HOMEにインストールされます。この項では、Oracle CMSを使用するための環境設定について説明します。次の項目について説明します。

5.2.1 システム要件

Oracle CMSを使用するには、システムにJava Development Kit(JDK)バージョン1.5以上が必要です。

5.2.2 CLASSPATH環境変数の設定

CLASSPATH環境変数には、必要なjarファイルおよびclassファイルすべてのフルパスとファイル名を指定してください。次の項目をCLASSPATHに指定します。

  • osdt_core.jarファイル

  • osdt_cert.jarファイル

  • osdt_cms.jarファイル

5.2.2.1 WindowsでのCLASSPATHの設定

WindowsでCLASSPATHを設定する手順を次に示します。

  1. Windowsの「コントロール パネル」で「システム」を選択します。

  2. 「システムのプロパティ」ダイアログで「詳細設定」タブを選択します。

  3. 「環境変数」をクリックします。

  4. ユーザー環境変数のセクションで「新規」をクリックし、CLASSPATH環境変数をユーザー・プロファイルに追加します。CLASSPATH環境変数がすでに存在している場合は、選択して「編集」をクリックします。

  5. 必要な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;
    
  6. 「OK」をクリックします。

5.2.2.2 UNIXでのCLASSPATHの設定

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

5.3 Oracle CMSでのアプリケーションの開発

oracle.security.crypto.cmsパッケージでCMSオブジェクトの読取りと書込みを行うには、次の2つの方法があります。

Oracle CMSのAPIを使用すると、ネスト(ラップ)されたCMSオブジェクトを構築できます。ラップ数の制限はありません。

この項に含まれる内容は次のとおりです。

5.3.1 CMSオブジェクト・タイプ

アプリケーション開発者は、特定のCMSオブジェクト・タイプに注意する必要があります。これらについては、この後の項で説明します。

デタッチ・オブジェクトは、dataおよびreceiptコンテンツ・タイプに適用されます。これらのタイプでは、デタッチ・オブジェクトは保護されるコンテンツがないオブジェクトです。

デジェネレート・オブジェクトは、証明書専用のsigned-dataオブジェクトであり、signed-dataコンテンツ・タイプのみに定義されます。signed-dataオブジェクトに署名者がいない場合に該当します。通常は証明書の格納に使用され、ファイル拡張子p7bおよびp7cが関連付けられます。

外部署名はsigned-dataコンテンツ・タイプのみに定義されます。これは、基本的にはデタッチされたsigned-dataオブジェクトです。つまり、signed-dataオブジェクトには1名以上の署名者がありますが、署名付きコンテンツがsigned-dataオブジェクトに存在しません。

5.3.2 CMS***ContentInfoクラスを使用したCMSオブジェクトの構成

表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クラスについては、この後で詳しく説明します。

5.3.2.1 抽象基本クラスCMSContentInfo

CMSContentInfoは、基本的なCMSオブジェクトを表す抽象クラスです。表5-2に、CMSContentInfoのサブクラスを示しています。

この抽象クラスの有用なメソッドの一部を、表5-3に示します。

表5-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)

オブジェクトのエンコーディングを所定の出力ストリームに書き込みます。


5.3.2.1.1 CMSオブジェクトの構成

CMSオブジェクトを構成する手順を次に示します。

  1. 指定されたコンテンツ・タイプのオブジェクトを作成します。

  2. オブジェクトを初期化します。

  3. output(..)メソッドをコールして、オブジェクト・エンコーディングを書き込みます。

既存のCMSContentInfoを読み取る際、事前に具体タイプがわからない場合には、inputInstance()を使用します。新しいオブジェクトを作成するには、作業している具体サブクラスのいずれかのコンストラクタを使用します。読取り時に具体タイプがわかっている場合は、引数なしのコンストラクタを使用し、input()メソッドを呼び出します。

5.3.2.1.2 CMSオブジェクトの読取り

オブジェクトを読み取る手順を次に示します。

  1. CMSContentInfo.inputInstance(..)をコールしてオブジェクトを読み取ります。

  2. getContentType()をコールしてコンテンツ・タイプを判別します。

  3. これでコンテンツ・タイプに対応する操作を呼び出すことができます。

5.3.2.2 CMSDataContentInfoクラス

クラスCMSDataContentInfoは、定数CMS.id_dataで定義されるid-dataタイプのオブジェクトを表し、任意の8ビット文字列を指します(文字列の解釈はアプリケーションに任されます)。

このクラスの有用なメソッドを次に示します。

byte[] getData()

これは、dataオブジェクトに格納されているデータを返します。

CMS dataオブジェクトを作成する手順を次に示します。

  1. 情報を含むバイト配列documentBytesをとるコンストラクタを使用して、次のようにCMSDataContentInfoのインスタンスを作成します。

    CMSDataContentInfo exdata =
        new CMSDataContentInfo(byte[] documentBytes)
    
  2. dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。

    exdata.output(new FileOutputStream("data.p7m"));
    

CMS dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。

  1. 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;
       // .....
    }
    
  2. 次のようにCMS dataオブジェクトに格納されている情報にアクセスします。

    byte[] docBytes = exdata.getData();
    

5.3.2.3 ESSReceiptクラス

クラス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オブジェクトを作成する手順を次に示します。

  1. コンテンツ・タイプの識別子、署名付きコンテンツ識別子を含むバイト配列、および発信者の署名値を含むバイト配列をとるコンストラクタを使用して、次のようにESSReceiptのインスタンスを作成します。

    ESSReceipt rcpt =
        new ESSReceipt(contentType, signedContentIdentifier,
        originatorSignatureValue);
    
  2. receiptオブジェクトをファイル(たとえばdata.p7m)に書き込みます。

    rcpt.output(new FileOutputStream("data.p7m"));
    

注意:

ESSReceiptオブジェクトを作成する場合は、入力パラメータの設定をnullのままにしないでください。

receiptオブジェクトを読み取る手順を次に示します。

  1. 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;
        // .....
    }
    
  2. receiptオブジェクトに格納されている情報に次のようにアクセスします。

    ASASN1ObjectID contentType = rcptdata.getReceiptContentType();
    byte[] sciBytes = rcptdata.getSignedContentIdentifier()
    byte[] osvBytes = rcptdata.getOriginatorSignatureValue();
    

5.3.2.4 CMSDigestedDataContentInfoクラス

クラスCMSDigestedDataContentInfoは、定数CMS.id_digestedDataで定義されるタイプid-digestedDataのオブジェクトを表します。

表5-5に、このクラスの有用なメソッドの一部を示します。

表5-5 CMSDigestedDataContentInfoの有用なメソッド

メソッド 説明

byte[] getDigest()

メッセージ・ダイジェスト値を返します。

AlgorithmIdentifier getDigestAlgID()

メッセージ・ダイジェストのアルゴリズムIDを返します。

CMSContentInfo getEnclosed()

ダイジェスト済コンテンツを返します。

ASN1ObjectID getEnclosedContentType()

ダイジェスト済コンテンツのコンテンツ・タイプを返します。

ASN1Integer getVersion()

このオブジェクトのバージョン番号を返します。

boolean isDetached()

このオブジェクトがデタッチされているかどうかを示します。

void setEnclosed(CMSContentInfo content)

カプセル化されたコンテンツ(つまりダイジェストされた元のオブジェクト)を設定します。

void writeDetached(boolean writeDetached)

CMSDigestedDataContentInfoオブジェクトを作成する場合に、ダイジェスト対象のオブジェクトを省略する必要があるかどうかを示します。


 

5.3.2.4.1 CMS digested-dataオブジェクトの構成

CMS digested-dataオブジェクトを作成する手順を次に示します。

  1. ダイジェスト対象のオブジェクトとダイジェスト・アルゴリズム識別子をとるコンストラクタを使用して、CMSDigestedDataContentInfoのインスタンスを作成します。たとえば、contentInfoがCMSDataContentInfoオブジェクト、MD5がダイジェスト・アルゴリズムの場合は、次のようになります。

    CMSDigestedDataContentInfo dig =
        new CMSDigestedDataContentInfo(contentInfo, CMS.md5);
    
  2. CMS digested-dataオブジェクトをdata.p7mというファイルに書き込みます。

    dig.output(new FileOutputStream("data.p7m"));
    
5.3.2.4.2 CMS digested-dataオブジェクトの読取り

CMS digested-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。

  1. 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;
        // .....
    }
    
  2. 次のように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;
    
  3. 保護されるデータの整合性を確認するために、次のようにダイジェストを検証します。

    digData.verify();
    
5.3.2.4.3 デタッチされたdigested-dataオブジェクト

デタッチ・オブジェクトを扱う場合、ダイジェストされたオブジェクトは、結果として生成されるCMS digested-data構造体には含まれません。デタッチ・オブジェクトを生成するには、writeDetached (true | false)メソッドをコールします。次に例を示します。

dig.writeDetached(true);

前述のとおり、デタッチされたCMS digested-dataオブジェクトを読み取ることはできますが、ダイジェストされた元のオブジェクトが存在しないため、ダイジェストの検証は失敗します。これを解決するためには、次のようにsetEnclosed (CMScontentInfo)メソッドをコールしてdigestedContentを設定します。

digdata.setEnclosed(CMScontentInfo object);

この後で、次のようにダイジェストの検証をします。

digdata.verify();

5.3.2.5 CMSSignedDataContentInfoクラス

クラスCMSSignedDataContentInfoは、定数CMS.id_signedDataで定義されるタイプid-signedDataのオブジェクトを表します。

Oracle CMSでは、SignerIdentifierとして使用するためにIssuerAndSerialNoまたはSubjectKeyIdentifierの選択がサポートされます。ただし、PKCS #7およびS/MIMEとの相互運用性を保つためには、IssuerAndSerialNoSignerIdentifierとして使用する必要があります。

表5-6に、このクラスの有用なメソッドの一部を示します。

表5-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オブジェクトの署名を列挙の形式で返します。列挙の各要素はCMSSignerInfoのインスタンスです。

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実装でプラッガブルになることに注意してください。

5.3.2.5.1 CMS signed-dataオブジェクトの構成

CMS signed-dataオブジェクトを作成する手順を次に示します。

  1. CMSSignedDataContentInfoのインスタンスを作成します。たとえば、CMSSignedDataContentInfoオブジェクトを作成するには、contentInfoオブジェクト(署名の対象になるデータ)を次のように渡します。

    CMSSignedDataContentInfo sig =
        new CMSSignedDataContentInfo(contentInfo);
    
  2. 署名を追加します。

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate envCert =  (X509Certificate)cf.generateCertificate(new FileInputStream("name1"));
    PrivateKey signerKey =
        ...;
    
    1. 次のように、IssuerAndSerialNoをSignerIdentifierとして使用し、MD5ダイジェストおよびRSA署名アルゴリズムを使用して、署名を追加します。

      sig.addSignature(null, signerKey, signerCert, CMS.md5,
          CMS.rsaEncryption, null);
      
    2. 次のように、64ビットSubjectKeyIdentifierをSignerIdentifierとして使用し、SHA-1ダイジェストおよびDSS署名アルゴリズムを使用して、署名を追加します。

      sig.addSignature(null, signerKey, signerCert, CMS.sha_1,
          CMS.dsaWithSHA, null, true);
      
    3. 次のように、160ビットSubjectKeyIdentifierをSignerIdentifierとして使用し、SHA-1ダイジェストおよびRSA署名アルゴリズムを使用して、署名を追加します。

      sig.addSignature(null, signerKey, signerCert, CMS.sha_1,
          CMS.rsaEncryption, null, false);
      
  3. 証明書とCRLを追加します。

    sig.addCertificate (....)
    sig.addCRL (...)
    
  4. CMS signed-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。

    sig.output(new FileOutputStream("data.p7m"));
    
5.3.2.5.2 CMS signed-dataオブジェクトの読取り

CMS signed-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。

  1. 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;
        // .....
    }
    
  2. 次のように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;
    
  3. 署名者の公開鍵証明書を使用して署名を検証します。

    sigData.verifySignature(signerCert);
    
  4. 次のように署名者の詳細を取得します。

    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();
    
5.3.2.5.3 外部署名(デタッチ・オブジェクト)

デタッチ・オブジェクトの場合、結果として生成されるCMS signed-data構造体に署名付きオブジェクトは含まれません。デタッチ・オブジェクトを生成するには、writeExternalSignature()メソッドをコールします。

sig.writeExternalSignature(true);

「CMS signed-dataオブジェクトの読取り」で説明したとおり、デタッチされたCMS signed-dataオブジェクトを読み取ることはできますが、署名付きの元のオブジェクトが存在しないため、署名の検証は失敗します。これに対処するには、次のようにsetEnclosed(..)メソッドを最初にコールして、署名付きコンテンツを設定します。

sigdata.setEnclosed(contentInfo);

この後で、次のように署名の検証をします。

sigdata.verifySignature(signerCert);
5.3.2.5.4 証明書またはCRL専用オブジェクト

これらは本質的には、署名のないCMSSignedDataContentInfoオブジェクトです。証明書またはCRL(あるいはその両方)が添付されています。次のように証明書またはCRL専用オブジェクトを生成します。

CMSSignedDataContentInfo sigdata = 
    new CMSSignedDataContentInfo(new CMSDataContentInfo(new byte[0]));
sigData.addCertificate (...);
sigData.addCRL( ...);
sigData.output(..);

証明書またはCRL専用signed-dataオブジェクトの読取りは、「CMS signed-dataオブジェクトの読取り」と同様に行うことができます。

5.3.2.6 CMSEncryptedDataContentInfoクラス

クラスCMSEncryptedDataContentInfoは、定数CMS.id_encryptedDataで定義されるタイプid-encryptedDataのオブジェクトを表します。

表5-7に、このクラスの有用なメソッドの一部を示します。

表5-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実装でプラッガブルになることに注意してください。

5.3.2.6.1 CMS encrypted-dataオブジェクトの構成

次のようにencrypted-dataオブジェクトを作成します。

  1. CMSEncryptedDataContentInfoのインスタンスを作成します。たとえば、contentInfoCMSDataContentInfoオブジェクト、暗号がCBCモードのTriple-DESの場合は、次のようになります。

    SecretKey contentEncryptionKey =    KeyGenerator.getInstance("DESede").generateKey();
     
    CMSEncryptedDataContentInfo enc =
       new CMSEncryptedDataContentInfo(contentInfo, contentEncryptionKey,
          CMS.des_ede3_cbc);
    
  2. encrypted-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。

    enc.output(new FileOutputStream("data.p7m"));
    
5.3.2.6.2 CMS encrypted-dataオブジェクトの読取り

encrypted-dataオブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。

  1. 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;
        // .....
    }
    
  2. 次のように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;
    
5.3.2.6.3 デタッチされたCMS encrypted-dataオブジェクト

デタッチ・オブジェクトの場合、結果として生成されるCMS encrypted-data構造体に暗号化されたオブジェクトは含まれません。デタッチ・オブジェクトを生成するには、writeDetached(..)メソッドをコールします。

encData.writeDetached(true);

「CMS encrypted-dataオブジェクトの読取り」で説明したとおり、デタッチされたCMS encrypted-dataオブジェクトを読み取ることはできますが、暗号化された元のオブジェクトが存在しないため、コンテンツの復号化は失敗します。setEnclosed (..)メソッドをコールして、encryptedContentを設定します。

encData.setEnclosed(encryptedcontent());

この後で、次のようにコンテンツを復号化します。

encdata.getEnclosed(ContentEncryptionKey);

5.3.2.7 CMSEncryptedDataContentInfoクラス

クラスCMSEnvelopedDataContentInfoは、定数CMS.id_envelopedDataで定義されるタイプid-envelopedDataのオブジェクトを表します。

表5-8に、このクラスの有用なメソッドの一部を示します。

表5-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)

このオブジェクトの出力エンコーディングから暗号化されたコンテンツを省略する必要があるかどうかを示します。


5.3.2.7.1 CMS enveloped-dataオブジェクトの構成

enveloped-dataオブジェクトを作成する手順を次に示します。

  1. CMSEnvelopedDataContentInfoのインスタンスを作成します。たとえば、contentInfoがCMSDataContentInfoオブジェクト、暗号がCBCモードのTriple-DESの場合は、次のようになります。

    CMSEnvelopedDataContentInfo env = 
        new CMSEnvelopedDataContentInfo(contentInfo, CMS.des_ede3_cbc);
    
    
  2. 受信者の鍵管理方法を考慮して、受信者を追加します。

    • 受信者が鍵暗号化(ラップ)鍵管理メカニズムを使用する場合:

      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)
      
  3. オプションの引数を設定します。

    env.setOriginatorInfo(originatorInfo);
    env.setUnprotectedAttribs(unprotectedAttributes);
    
  4. CMS enveloped-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。

    enc.output(new FileOutputStream("data.p7m"));
    
5.3.2.7.2 CMS enveloped-dataオブジェクトの読取り

オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。

  1. 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;
        // 
        .....
    }
    
  2. 次のように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();
    
  3. 次のように、受信者の情報に応じてコンテンツを復号化します。

    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;
        // ...
    }
    
5.3.2.7.3 鍵転送鍵交換メカニズム

このメカニズムでは、受信者識別子としてIssuerAndSerialNoまたはSubjectKeyIdentifierがサポートされます。

5.3.2.7.4 鍵合意鍵交換メカニズム

このメカニズムは現在サポートされていません。

5.3.2.7.5 鍵暗号化(ラップ)鍵交換メカニズム

Oracle CMSでは、CMS3DESWrapおよびCMSRC2Wrapアルゴリズムがサポートされます。混在モードのラップはサポートされません。たとえば、3DESの鍵をRC2でラップすることはできません。


注意:

OtherKeyAttributeを使用すると、相互運用性の問題が発生する場合があります。

5.3.2.7.6 デタッチされたCMS enveloped-dataオブジェクト

デタッチ・オブジェクトを扱う場合、結果として生成されるCMS enveloped-data構造体にエンベロープ・オブジェクトは含まれません。デタッチ・オブジェクトを生成するには、writeDetached(..)メソッドをコールします。

envdata.writeDetached(true);

「CMS enveloped-dataオブジェクトの読取り」で説明したとおり、デタッチされたenveloped-dataオブジェクトを読み取ることはできますが、元のエンベロープ・オブジェクトが存在しないため、コンテンツの復号化は失敗します。setEnclosed(..)メソッドをコールして、エンベロープ・コンテンツを設定します。

envdata.setEnclosed(env.getEncryptedContent());

この後で、次のようにコンテンツを復号化します。

envdata.getEnclosed(............);

5.3.2.8 CMSAuthenticatedDataContentInfoクラス

クラスCMSAuthenticatedDataContentInfoは、定数CMS.id_ct_authDataで定義されるid-ct-authDataタイプのオブジェクトを表します。


注意:

Oracle CMSでは、HMAC-SHA1メッセージ認証コード(MAC)アルゴリズムがサポートされます。

表5-9に、このクラスの有用なメソッドの一部を示します。

表5-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)

このオブジェクトの出力エンコーディングから認証されたコンテンツを省略する必要があるかどうかを示します。




5.3.2.8.1 CMS authenticated-dataオブジェクトの構成

authenticated-dataオブジェクトを作成する手順を次に示します。

  1. CMSAuthenticatedDataContentInfoのインスタンスを作成します。次の例では、contentInfoがCMSDataContentInfoオブジェクト、鍵がTriple-DES HMAC、アルゴリズムがHMAC-SHA1になります。

    SecretKey contentEncryptionKey = 
       KeyGenerator.getInstance("DESede").generateKey();
    CMSAuthenticatedDataContentInfo auth = 
        new CMSAuthenticatedDataContentInfo(contentInfo, 
    contentEncryptionKey, CMS.hmac_SHA_1);
    
  2. 受信者の鍵管理方法を考慮して、受信者を追加します。

    • 受信者が鍵暗号化(ラップ)鍵管理メカニズムを使用する場合:

      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)
      
  3. オプションの引数を設定します。

    auth.setAuthenticatedAttributes(authenticatedAttributes, CMS.md5);
    auth.setOriginatorInfo(originatorInfo);
    auth.setUnauthenticatedAttributes(unauthenticatedAttributes);
    
  4. CMS authenticated-dataオブジェクトをファイル(たとえばdata.p7m)に書き込みます。

    auth.output(new FileOutputStream("data.p7m"));
    
5.3.2.8.2 CMS authenticated-dataオブジェクトの読取り

オブジェクトの読取り手順は、オブジェクトのコンテンツ・タイプがわかっているかどうかによって異なります。

  1. 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;
       // .....
    }
    
  2. 次のように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;
    
  3. 次のように、受信者の情報に応じてMACを検証します。

    authdata.verifyMAC(recipientPrivateKey, recipientCert);
    

    または

    authdata.verifyMAC(symmetricKey, keyIdentifier)
    

    または

    authdata.verifyMAC(symmetricKey, keyIdentifier, keyDate)
    

    または

    authdata.verifyMAC(symmetricKey, keyIdentifier, keyDate,
        otherKeyAttribute)
    
5.3.2.8.3 デタッチされたCMS authenticated-dataオブジェクト

前述のとおり、デタッチされたauthenticated-dataオブジェクトを読み取ることはできますが、認証された元のオブジェクトが存在しないため、MACの検証は失敗します。これを解決するためには、次のようにsetEnclosed(..)メソッドをコールして認証されたコンテンツを設定します。

authdata.setEnclosed(contentInfo);

この後で、適切な鍵交換メカニズムを使用して、次のようにMACを検証します。

authdata.verifyMAC(...)

5.3.2.9 3回以上ラップされたCMSContentInfoオブジェクト

CMSContentInfoオブジェクトを別のCMSContentInfoオブジェクトでラップするには、コンストラクタを介して、初期化したCMSContentInfoオブジェクトを外側のCMSContentInfoオブジェクトに渡します。一番外側のCMSContentInfoオブジェクトのoutput(..)メソッドをコールして、ネストしたオブジェクトを生成します。

5.3.2.9.1 ネスト(ラップ)したCMSオブジェクトの読取り

ネストしたオブジェクトの読取り方法は、事前に一番外側のコンテンツ・タイプがわかっているかどうかによって異なります。

一番外側のコンテンツ・タイプが事前にわからない場合は、次のように静的なメソッドをコールします。

CMSContentInfo.inputInstance( ... )

一番外側のコンテンツ・タイプが事前にわかっている場合は、次のように適切なコンストラクタをコールします。

new CMS***DataContentInfo( .... )

その後、getEnclosed(..)メソッドを再帰コールし、内側のオブジェクトを1つずつ抽出します。

5.3.3 CMS***StreamおよびCMS***Connectorクラスを使用したCMSオブジェクトの構成

CMS**DataContentInfoクラスにより、CMS***Streamクラスと同じ機能が提供されます。CMS**DataContentInfoクラスに対するCMS***Streamクラスの最大の利点は、1つのパスでCMSオブジェクトの作成または読取りが可能であり、必要なすべての情報を累積する必要がないことです。

表5-10に、CMS***Streamクラスのコンテンツ・タイプを示します。

表5-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


表5-11に、CMS***Connectorクラスのコンテンツ・タイプを示します。

表5-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


5.3.3.1 CMS***StreamおよびCMS***Connectorクラスの制限

オブジェクトを処理する場合、CMS***StreamクラスおよびCMS***Connectorクラスには次の制限があります。

  1. デタッチされたCMS id-digestedDataオブジェクトのダイジェストを検証できません。

  2. デタッチされたCMS id-signedDataオブジェクトの署名を検証できません。

  3. デタッチされたCMS id-ct-authDataオブジェクトのMACを検証できません。


注意:

デタッチ・オブジェクトを処理する場合は、常にCMS**DataContentInfoクラスを使用してください。

5.3.3.2 CMS***StreamとCMS***Connectorクラスの違い

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は、ネストしたオブジェクトの作成と読取りを行う場合に便利です。

5.3.3.3 CMS***OutputStreamおよびCMS***InputStreamクラスの使用

オブジェクトを構成する手順を次に示します。

  1. 適切なコンテンツ・タイプのCMS***OutputStreamクラスを作成します。関連するすべてのパラメータはコンストラクタを介して渡されます。

  2. ステップ1で作成したCMS***OutputStreamに、保護するデータを書き込みます。

  3. すべてのデータを書き込んだら、ステップ1で作成したCMS***OutputStreamを閉じます。

オブジェクトを読み取る手順を次に示します。

  1. 基礎となる入力ストリームをコンストラクタを介して渡し、適切なコンテンツ・タイプのCMS***InputStreamクラスを作成します。

  2. read()およびread (byte[],...)メソッドを使用して、ステップ1で作成したCMS***InputStreamから、保護されているデータを読み取ります。

  3. ステップ1で作成したCMS***InputStreamからのデータの読取りが終了したら、terminate()を呼び出します。これで、オブジェクトの読取りが完了します。

  4. 適切なメソッドを呼び出して、保護されているデータが安全であることを確認します。

5.3.3.3.1 CMS id-dataオブジェクト

getData()メソッドから返されるデータは、CMS***OutputStreamまたはCMS***OutputConnectorに書き込むことができます。

5.3.3.3.2 CMS id-ct-receiptオブジェクト

getReceiptData()メソッドから返されるエンコード済receiptは、CMS***OutputStreamまたはCMS***OutputConnectorに書き込むことができます。

次のように入力ストリームからESSReceiptデータを読み取ります。

byte[] rcptData = in.read(...);
ESSReceipt er = new ESSReceipt();
er.inputContent(rcptData);
5.3.3.3.3 CMS id-digestedDataオブジェクト

デタッチされたdigested-dataオブジェクトのダイジェストを検証することはできません。CMSDigestedDataOutputStreamコンストラクタのブール値のパラメータwriteEContentInfoをfalseに設定すると、デタッチされたdigested-dataオブジェクトを作成できるようになります。

5.3.3.3.4 CMS id-signedDataオブジェクト

デタッチされたsigned-dataオブジェクトの署名を検証することはできません。

CMSSignerInfoSpecクラスには署名者固有の情報が格納されます。追加する署名ごとに、対応するCMSSignerInfoSpecオブジェクトを作成して、コンストラクタに渡す必要があります。

CMSSignedDataOutputStreamコンストラクタのブール値のパラメータcreateExternalSignaturesをtrueに設定すると、デタッチされたsigned-dataオブジェクトすなわち外部署名を作成できるようになります。

証明書またはCRL専用オブジェクトを作成する場合は、署名者情報をCMSDSignedDataOutputStreamコンストラクタに渡さないでください。

5.3.3.3.5 CMS id-encryptedDataオブジェクト

CMSEncryptedDataOutputStreamコンストラクタのブール値のパラメータwriteEncryptedOutputをfalseに設定すると、デタッチされたencrypted-dataオブジェクトを作成できるようになります。

5.3.3.3.6 CMS id-envelopedDataオブジェクト

CMSRecipientInfoSpecクラスには受信者固有の情報が格納されます。追加する受信者ごとに、対応するCMSRecipientInfoSpecオブジェクトを作成して、コンストラクタに渡す必要があります。

CMSEnvelopedDataOutputStreamコンストラクタのブール値のパラメータwriteContentfalseに設定すると、デタッチされたenveloped-dataオブジェクトを作成できるようになります。

鍵転送鍵交換メカニズム

CMSKeyTransRecipientInfoSpecクラスを使用して、鍵転送鍵管理メカニズムを使用する受信者情報を格納します。

鍵合意鍵交換メカニズム

このメカニズムは現在サポートされていません。

鍵暗号化(ラップ)鍵交換メカニズム

CMSKEKRecipientInfoSpecクラスを使用して、鍵ラップ鍵管理メカニズムを使用する受信者情報を格納します。

5.3.3.3.7 CMS id-ct-authDataオブジェクト

デタッチされたauthenticated-dataオブジェクトのMACを検証することはできません。

CMSAuthenticatedDataOutputStreamコンストラクタのブール値のパラメータdetachEncapContentをtrueに設定すると、デタッチされたauthenticated-dataオブジェクトを作成できるようになります。

5.3.3.4 CMS***Connectorオブジェクトの3回以上のラップ

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);

5.4 Oracle CMSのJava APIリファレンス

Oracle CMSのAPIリファレンス(Javadoc)は次のドキュメントで参照できます。

Oracle Fusion Middleware CMS Java API Reference for Oracle Security Developer Tools

5.5 サンプル・プログラム

Oracleセキュリティ開発ツールを使用したサンプル・プログラムについては、Oracle Technology Network Webサイト(http://www.oracle.com/technology/sample_code/products/id_mgmt/index.html)を参照してください。