消息编码和解码过程

对常规消息进行编码的过程如下所示。

对消息进行编码

  1. 初始化所需数据类型的相应数据结构。
  2. 调用 CryptMsgOpenToEncode,传递必要的参数。 调用 CryptMsgOpenToEncode 时,如果要提供给 CryptMsgUpdate 的数据已经过消息编码,请在 pszInnerContentObjID (传递相应的对象标识符,例如,szOID_RSA_signedData) 的“1.2.840.113549.1.7.2”。 如果 pszInnerContentObjIDNULL,则假定 内部内容类型 之前未经过编码,并经过适当处理。
  3. 根据需要多次调用 CryptMsgUpdate 以完成消息。 在最后一次调用中,将 fFinal 参数设置为 TRUE。 (有关详细信息,请参阅 CryptMsgUpdate) 。
  4. 调用 CryptMsgGetParam 以获取指向所需参数(如内容)的指针。 若要对简单常规数据进行编码,请使用 dwParamtype 的 CMSG_CONTENT_PARAM。
  5. 通过调用 CryptMsgClose 关闭消息。

此过程将生成函数调用中指定的类型的编码消息。

解码常规消息的过程如下所示。

解码消息

  1. 使用 CryptMsgCalculateEncodedLength 确定缓冲区保存编码数据所需的长度。
  2. 调用 CryptMsgOpenToDecode,传递必要的参数。 为了保持与 Internet Explorer 版本 3.0 的兼容性,提供了 dwMsgType 参数。 在 Internet Explorer 3.0 中创建的签名数据不包含标头信息。 因此,如果此类消息是从文件签名中提取的,则必须将消息类型传递到 函数中。 如果将零传递到 dwMsgType 参数中,该函数将从消息的 标头中读取消息类型。 如果缺少标头,函数调用将失败。 如果成功,则返回已打开消息的句柄。
  3. 调用 CryptMsgUpdate 一次。 这会导致根据消息类型对消息采取适当的操作。
  4. 若要对消息进行其他处理(例如其他解密或签名验证),请调用 CryptMsgControl,并在 dwCtrlType 中传递所需的操作。
  5. 调用 CryptMsgGetParam 以获取指向所需参数(如内容)的指针。 若要解码简单的常规数据,请对 dwParamtype 参数使用 CMSG_CONTENT_PARAM。
  6. 调用 CryptMsgClose 以关闭消息。

有关实现这些步骤的示例,请参阅 示例 C 程序:编码和解码数据。 有关演示已签名消息编码、解码和验证签名过程的过程和示例,请参阅 示例 C 程序:签名、编码、解码和验证消息