Share via


エンベロープ データのエンコード

エンベロープ データは、任意の種類の暗号化されたコンテンツと、1 人以上の受信者の暗号化されたコンテンツ暗号化セッション キーで構成されます。 エンベロープ メッセージは、メッセージ シークレットの内容を保持し、指定されたユーザーまたはエンティティのみがコンテンツを取得できるようにします。

暗号化メッセージ構文 (CMS) を使用して、エンベロープ メッセージをエンコードできます。 CMS では、キー トランスポート、キー アグリーメント、および以前に分散された対称キー暗号化キー (KEK) の 3 つのキー管理手法がサポートされています。 以前に分散された対称 KEK は、メーリング リスト キー配布とも呼ばれます。

これら 3 つの手法のそれぞれで、エンベロープされたメッセージを暗号化するために 1 つのセッション キーが生成されます。 キー管理の問題は、セッション キーが送信者によって暗号化され、受信側によって暗号化解除される方法に対処します。 キー管理手法を組み合わせ、1 つの暗号化されたメッセージを多数の受信者に配布できます。

キー トランスポート キー管理では、目的の受信者の公開キーを使用してセッション キーを暗号化します。 受信側は、暗号化に使用された公開キーに関連付けられている秘密キーを使用してセッション キーの暗号化を解除します。 その後、受信側は暗号化解除されたセッション キーを使用して、エンベロープされたデータの暗号化を解除します。 キートランスポートを使用する場合、受信側は送信者の ID に関する情報を確認していません。

キー アグリーメント管理では、一時的なエフェメラル Diffie-Hellman秘密キーが生成され、セッション キーの暗号化に使用されます。 エフェメラル秘密キーに対応する公開キーは、メッセージの受信者情報の一部として含まれます。 受信者は、受信したエフェメラル キーを使用してセッション キーの暗号化を解除し、この復号化されたセッション キーを使用して、エンベロープされたメッセージの暗号化を解除します。 一時的なキーアグリーメントを受信側の秘密キーと組み合わせて使用すると、メッセージ受信者は送信者の ID に関する情報を確認します。

以前に分散された 対称キーを使用したキー管理の場合、各メッセージには、以前に分散されたキー暗号化キーで暗号化されたコンテンツ暗号化キーが含まれます。 受信側は、以前に分散されたキー暗号化キーを使用してコンテンツ暗号化キーの暗号化を解除し、暗号化解除されたコンテンツ暗号化キーを使用して、エンベロープされたメッセージの暗号化を解除します。

エンベロープ データをエンコードするための一般的な CMS イベント シーケンスを次の図に示します。

エンベロープ データのエンコード

  • プレーンテキスト メッセージへのポインターが取得されます。
  • 対称 (セッション) キーが生成されます。
  • 対称キーと指定された暗号化アルゴリズムは、メッセージ データの暗号化に使用されます。
  • 証明書ストアが開きます。
  • 受信者の証明書がストアから取得されます。
  • 公開キーは、受信者の証明書から取得されます。
  • 受信者の公開キーを使用して、対称キーが暗号化されます。
  • 受信者の証明書から、受信者の ID が取得されます。
  • デジタルエンベロープ メッセージには、データ暗号化アルゴリズム、暗号化されたデータ、暗号化された対称キー、受信者情報構造という情報が含まれます。

低レベルのメッセージ関数を使用して、一覧表示されている一般的なタスクを実行するには、次の手順を使用します。

エンベロープ メッセージをエンコードするには

  1. コンテンツを作成または取得します。

  2. 暗号化プロバイダーを取得します。

  3. 受信者証明書を取得します。

  4. CMSG_ENVELOPED_ENCODE_INFO構造体を初期化します。

  5. CryptMsgCalculateEncodedLength を呼び出して、エンコードされたメッセージ BLOB のサイズを取得します。 メモリを割り当てます。

  6. CryptMsgOpenToEncode を呼び出し、dwMsgType のCMSG_ENVELOPEDと pvMsgEncodeInfoCMSG_ENVELOPED_ENCODE_INFOへのポインターを渡します。 この呼び出しの結果として、開かれたメッセージへのハンドルが取得されます。

  7. CryptMsgUpdate を呼び出し、手順 6 で取得したハンドルと、暗号化、エンベロープ、エンコードされるデータへのポインターを渡します。 この関数は、エンコード プロセスを完了するために必要な回数だけ呼び出すことができます。

  8. CryptMsgGetParam を呼び出し、手順 6 で取得したハンドルと適切なパラメーター型を渡して、目的のエンコードされたデータにアクセスします。 たとえば、CMSG_CONTENT_PARAMを渡して、PKCS #7 メッセージ全体へのポインターを取得します。

    このエンコードの結果を、エンベロープ メッセージなどの別のエンコードされたメッセージの 内部データ として使用する場合は、CMSG_BARE_CONTENT_PARAM パラメーターを渡す必要があります。 例については、「 エンベロープ メッセージをエンコードするための代替コード」を参照してください。

  9. CryptMsgClose を呼び出してメッセージを閉じます。

この手順の結果は、暗号化されたデータ、受信者の公開キーで暗号化された 対称キー 、および受信者情報データ構造を含むエンコードされたメッセージです。 暗号化されたコンテンツと受信者の暗号化された対称キーの組み合わせは、その受信者の デジタル エンベロープ です。 複数の受信者に対して任意の種類のコンテンツをエンベロープできます。

例 C プログラム: エンベロープされた署名付きメッセージをエンコードする