Encoding Enveloped Data

Enveloped data consists of encrypted content of any type and encrypted content-encryption session keys for one or more recipients. Enveloped messages keep the contents of the message secret and allow only specified persons or entities to retrieve the contents.

Cryptographic message syntax (CMS) can be used to encode enveloped messages. CMS supports three key management techniques: key transport, key agreement, and previously distributed symmetric key-encryption keys (KEK). Previously distributed symmetric KEK are also known as mailing list key distribution.

In each of these three techniques, a single session key is generated to encrypt the enveloped message. Key management issues deal with the way that session key is encrypted by the sender and decrypted by a receiver. A single encrypted message can be distributed to many recipients using a mixture of the key management techniques.

Key transport key management uses an intended receiver's public key to encrypt the session key. The receiver decrypts the session key using the private key associated with the public key that was used to encrypt. The receiver then uses the decrypted session key to decrypt the enveloped data. When key transport is used, the receiver has not confirmed information on the identity of the sender.

In key agreement management, a temporary, ephemeral Diffie-Hellman private key is generated and used to encrypt the session key. The public key corresponding to the ephemeral private key is included as part of the message's recipient information. The recipient decrypts the session key using the received ephemeral key and uses this decrypted session key to decrypt the enveloped message. Using ephemeral key agreement in conjunction with the receiver's private key, the message receiver does have confirmed information on the identity of the sender.

For key management using previously distributed symmetric keys, each message includes the content-encryption key that has been encrypted with a previously distributed key-encryption key. Receivers use the previously distributed key-encryption key to decrypt the content encryption key, then use the decrypted content-encryption key to decrypt the enveloped message.

A typical CMS sequence of events for encoding enveloped data, is shown in the following illustration.

encoding enveloped data

  • A pointer to the plaintext message is retrieved.
  • A symmetric (session) key is generated.
  • The symmetric key and specified encryption algorithm are used to encrypt the message data.
  • A certificate store is opened.
  • The recipient's certificate is retrieved from the store.
  • The public key is retrieved from the recipient's certificate.
  • Using the recipient's public key, the symmetric key is encrypted.
  • From the recipient's certificate, the recipient's ID is retrieved.
  • The following information is included in the digitally enveloped message: the data encryption algorithm, the encrypted data, the encrypted symmetric key, and the recipient information structure.

To use low-level message functions to accomplish the typical tasks just listed, use the following procedure.

To encode an enveloped message

  1. Create or retrieve the content.

  2. Get a cryptographic provider.

  3. Get a recipient certificate.

  4. Initialize the CMSG_ENVELOPED_ENCODE_INFO structure.

  5. Call CryptMsgCalculateEncodedLength to get the size of the encoded message BLOB. Allocate memory for it.

  6. Call CryptMsgOpenToEncode, passing in CMSG_ENVELOPED for dwMsgType and a pointer to CMSG_ENVELOPED_ENCODE_INFO for pvMsgEncodeInfo. As a result of this call, you will get a handle to the opened message.

  7. Call CryptMsgUpdate, passing in the handle retrieved in step 6 and a pointer to the data that is to be encrypted, enveloped, and encoded. This function can be called as many times as necessary to complete the encoding process.

  8. Call CryptMsgGetParam, passing in the handle retrieved in step 6 and the appropriate parameter types to access the desired, encoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the entire PKCS #7 message.

    If the result of this encoding is to be used as the inner data for another encoded message, such as an enveloped message, the CMSG_BARE_CONTENT_PARAM parameter must be passed. For an example, see Alternate Code for Encoding an Enveloped Message.

  9. Close the message by calling CryptMsgClose.

The result of this procedure is an encoded message that contains the encrypted data, the symmetric key that is encrypted with the recipient's public keys, and the recipient information data structures. The combination of encrypted content and an encrypted symmetric key for a recipient is a digital envelope for that recipient. Any type of content can be enveloped for multiple recipients.

Example C Program: Encoding an Enveloped, Signed Message