4 Oracle CMS

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

この章には次のトピックが含まれます:

4.1 Oracle CMSの機能と利点

Oracle CMS SDKは、CMSオブジェクトの読取りと書込みのためのツール、サンプル・プログラム、および安全なメッセージ・エンベロープを開発するためのサポート・ツールなど、豊富なツールを含むPure Java APIです。RFC 2630に指定されているIETF暗号メッセージ構文が実装されます。この構文は、メッセージのデジタル署名、ダイジェスト、認証および暗号化に使用されます。

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

関連項目:

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

4.1.1 Oracle CMSのコンテンツ・タイプ

Oracle CMSでは、署名付きデータ、エンベロープ・データ、暗号化データなど、様々なコンテンツ・タイプがサポートされます。RFC 2630に指定されているすべてのコンテンツ・タイプがサポートされます。RFC 2634に指定されているS/MIMEコンテンツ・タイプに対する拡張セキュリティ・サービスがサポートされます。RFC 3161に対応するIETF PKIXタイムスタンプ・プロトコルのコンテンツ・タイプもサポートされます。

表4-1 Oracle CMSでサポートされるコンテンツ・タイプ

タイプ 識別子

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コンテンツ・タイプに対する拡張セキュリティ・サービスがサポートされます。

タイプ 識別子

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へのリンクは、「リファレンス」を参照してください。

4.1.2 Oracle CMS実装とRFCの違い

Oracle CMSは、いくつかの点でPKCS #7 v 1.5 [RFC 2315]およびIETF CMS [RFC 2630]と異なります。PKCS#7実装との相互運用性が必要な場合は、これらの相違点について知っておく必要があります。

次のような相違点があります。

  • enveloped-dataにオプションのOriginatorInfoが含まれます。

  • RFC 2630では、エンベロープ・データに、保護されていないオプションの属性も含まれます。

  • signed-dataであるSignerInfoのSignerIdentifierとして、IssuerAndSerialNoまたはSubjectKeyIdentifierを選択できます。

  • RFC 2630では、署名付きデータにencapsulatedcontentinfoが含まれます。encapsulatedcontentinfoにはオプションのコンテンツが含まれますが、RFC 2315にはコンテンツ・データが含まれます。

注意:

PKCS#7実装との相互運用性が必要な場合は、これらの違いに注意してください。

4.2 Oracle CMSの環境設定

Oracle Security Developer Toolsは、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;

4.3 Oracle CMSによるアプリケーションの理解および開発

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

この項では、Oracle CMSのクラスについて紹介し、それにより使用可能になるCMSオブジェクトの開発に対する様々なアプローチと、オブジェクトの使用方法について説明します。

この項の内容は次のとおりです。

4.3.1 Oracle CMSクラスについて

Oracle CMSクラスは、CMSオブジェクトの読取りと書込みの機能を備えています。

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

  • CMSContentInfoクラスの使用。比較的簡単に使用できます。

  • 次のいずれかのクラスの使用:

    • CMSInputStream

    • CMSOutputStream

    • CMSInputConnector

    • CMSOutputConnector

    これらのクラスでは、CMSオブジェクトのシングル・パスでの読取りおよび書込み機能が提供され、出力を書き込む前に入力データを累積する必要がありません。

4.3.2 CMSのオブジェクト・タイプについて

CMSオブジェクトのタイプとして、デタッチされたオブジェクトデジェネレート・オブジェクトがあります。デタッチされたオブジェクトは、dataおよびreceiptコンテンツ・タイプに適用されます。デジェネレート・オブジェクトは、証明書専用のsigned-dataオブジェクトであり、signed-dataコンテンツ・タイプのみに定義されます。

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

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

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

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

CMS***ContentInfoクラスを使用して、適切なコンテンツ・タイプのオブジェクトの読取りと書込み、デタッチされたオブジェクトの構成と処理、およびネストしたオブジェクトの作成を行うことができます。

表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

4.3.3.1 抽象ベース・クラスCMSContentInfoの使用方法

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)

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

4.3.3.1.1 CMSオブジェクトの構成

コンテンツ・タイプを指定してCMSContentInfoオブジェクトを作成できます。

CMSオブジェクトを構成するステップを次に示します。

  1. 指定されたコンテンツ・タイプのオブジェクトを作成します。
  2. オブジェクトを初期化します。
  3. output(..)メソッドをコールして、オブジェクト・エンコーディングを書き込みます。

新しいオブジェクトを作成するには、作業している具体サブクラスのいずれかのコンストラクタを使用します。

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

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

オブジェクトを読み取るステップを次に示します。

  1. CMSContentInfo.inputInstance(..)をコールしてオブジェクトを読み取ります。
  2. getContentType()をコールしてコンテンツ・タイプを判別します。
  3. これでコンテンツ・タイプに対応する操作を呼び出すことができます。
4.3.3.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();
    
4.3.3.3 ESSReceiptクラスの使用方法

クラス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エンコーディングを読み取ることで、このオブジェクトを初期化します。

4.3.3.3.1 ESSReceiptオブジェクトの作成

CMS receiptオブジェクトを作成するステップを次に示します。

  1. コンテンツ・タイプの識別子、署名付きコンテンツ識別子を含むバイト配列、および発信者の署名値を含むバイト配列をとるコンストラクタを使用して、次のようにESSReceiptのインスタンスを作成します。
    ESSReceipt rcpt =
        new ESSReceipt(contentType, signedContentIdentifier,
        originatorSignatureValue);
    
  2. receiptオブジェクトをファイル(たとえばdata.p7m)に書き込みます。
    rcpt.output(new FileOutputStream("data.p7m"));

注意:

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

4.3.3.3.2 ESSReceiptオブジェクトの読み取り

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();
4.3.3.4 CMSDigestedDataContentInfoクラス

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

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

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

メソッド 説明

byte[] getDigest()

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

AlgorithmIdentifier getDigestAlgID()

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

CMSContentInfo getEnclosed()

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

ASN1ObjectID getEnclosedContentType()

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

ASN1Integer getVersion()

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

boolean isDetached()

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

void setEnclosed(CMSContentInfo content)

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

void writeDetached(boolean writeDetached)

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

4.3.3.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"));
    
4.3.3.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();
    
4.3.3.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();
4.3.3.5 CMSSignedDataContentInfoクラス

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

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

表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オブジェクトの署名を列挙の形式で返します。列挙の各要素は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実装でプラガブルになることに注意してください。

4.3.3.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"));
    
4.3.3.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();
    
4.3.3.5.3 外部署名(デタッチ・オブジェクト)の操作

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

sig.writeExternalSignature(true);

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

sigdata.setEnclosed(contentInfo);

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

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

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

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

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

4.3.3.6 CMSEncryptedDataContentInfoクラスの使用方法

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

4.3.3.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"));
    
4.3.3.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;
    
4.3.3.6.3 デタッチされた暗号化データCMSオブジェクトの生成

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

encData.writeDetached(true);

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

encData.setEnclosed(encryptedcontent());

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

encdata.getEnclosed(ContentEncryptionKey);
4.3.3.7 CMSEnvelopedDataContentInfoクラスの理解および使用方法

クラス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)

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

4.3.3.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"));
    
4.3.3.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;
        // ...
    }
    
4.3.3.7.3 キー転送キー交換メカニズムについて

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

4.3.3.7.4 キー合意キー交換メカニズムについて

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

4.3.3.7.5 キー暗号化(ラップ)キー交換メカニズムについて

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

注意:

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

4.3.3.7.6 デタッチされたCMS enveloped-dataオブジェクトの使用方法

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

envdata.writeDetached(true);

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

envdata.setEnclosed(env.getEncryptedContent());

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

envdata.getEnclosed(............);
4.3.3.8 CMSAuthenticatedDataContentInfoクラスの使用方法

クラス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)

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

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

authenticated-dataオブジェクトの使用の開始点はCMSAuthenticatedDataContentInfoクラスです。

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"));
    
4.3.3.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)
    
4.3.3.8.3 デタッチされたCMS authenticated-dataオブジェクトの操作

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

authdata.setEnclosed(contentInfo);

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

authdata.verifyMAC(...)
4.3.3.9 3回以上ラップされたCMSContentInfoオブジェクトの操作

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

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

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

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

CMSContentInfo.inputInstance( ... )

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

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

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

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

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

4.3.4.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クラスを使用してください。

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

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

CMS***InputStreamにはCMSオブジェクトを読み取るためのメソッドが含まれます。CMS***OutputStreamはCMSオブジェクトを出力ストリームに書き込みます。

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

  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. 適切なメソッドを呼び出して、保護されているデータが安全であることを確認します。
4.3.4.3.1 CMS id-dataオブジェクトの操作

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

4.3.4.3.2 CMS id-ct-receiptオブジェクトの操作

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

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

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

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

4.3.4.3.4 CMS id-signedDataオブジェクトの操作

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

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

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

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

4.3.4.3.5 CMS id-encryptedDataオブジェクトの操作

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

4.3.4.3.6 CMS id-envelopedDataオブジェクトの操作

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

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

受信者は交換メカニズムにより分類されます。次の表で、様々なメカニズムを定義します。

交換メカニズム 使用方法

キー転送キー交換メカニズム

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

キー合意キー交換メカニズム

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

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

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

4.3.4.3.7 CMS id-ct-authDataオブジェクトについて

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

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

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

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

Oracle CMSのクラスとメソッドについては、『Oracle Fusion Middleware Oracle Security Developer Tools Java APIリファレンス』を参照してください。

このガイドには、次のリンクからアクセスできます。

Oracle Fusion Middleware Oracle Security Developer Tools Java APIリファレンス