DecryptMessage (Schannel) 函数

DecryptMessage (Schannel) 函数解密消息。 某些包不会加密和解密消息,而是执行并检查完整性哈希

此函数还与 Schannel 安全支持提供程序 (SSP) 一起使用,以向消息发送方发出请求发出信号,要求重新协商 (重做) 连接属性或关闭连接。

备注

如果一个线程正在加密,另 (一个线程正在解密,则可以同时从单个安全支持提供程序接口中的两个不同线程调用 EncryptMessage ( (Schannel) 和 DecryptMessage ) ) 。 如果多个线程正在加密,或者多个线程正在解密,则每个线程应获取唯一的上下文。

语法

SECURITY_STATUS SEC_Entry DecryptMessage(
  _In_    PCtxtHandle    phContext,
  _Inout_ PSecBufferDesc pMessage,
  _In_    ULONG          MessageSeqNo,
  _Out_   PULONG         pfQOP
);

参数

phContext [in]

用于解密消息 的安全上下文 的句柄。

pMessage [in, out]

指向 SecBufferDesc 结构的指针。 输入时, 结构引用一个或多个 SecBuffer 结构。 其中一个可能属于SECBUFFER_DATA类型。 该缓冲区包含加密的消息。 加密的消息就地解密,覆盖其缓冲区的原始内容。

将 Schannel SSP 与非面向连接的上下文一起使用时,在输入时,结构必须包含四个 SecBuffer 结构。 只有一个缓冲区的类型SECBUFFER_DATA,并且必须包含已就地解密的加密消息。 其余缓冲区用于输出,并且必须是SECBUFFER_EMPTY类型。 对于面向连接的上下文,必须提供SECBUFFER_DATA类型缓冲区,如面向非连接的上下文所述。 此外,还必须提供包含安全令牌的第二个SECBUFFER_TOKEN类型缓冲区。

MessageSeqNo [in]

传输应用程序所需的序列号(如果有)。 如果传输应用程序不保留序列号,则必须将此参数设置为零。

使用 Schannel SSP 时,此参数必须设置为零。 Schannel SSP 不使用序列号。

pfQOP [out]

指向 ULONG 类型的变量的指针,该变量接收指示保护质量的包特定标志。

使用 Schannel SSP 时,不使用此参数,应设置为 NULL

此参数可以是以下标志。

含义
SECQOP_WRAP_NO_ENCRYPT
消息未加密,但生成了标头或尾部。
注意: KERB_WRAP_NO_ENCRYPT具有相同的值和含义。

返回值

如果函数验证是否按正确的顺序接收了消息,则函数将返回SEC_E_OK。

如果函数无法解密消息,它将返回以下错误代码之一。

返回代码 描述
SEC_E_INVALID_HANDLE phContext 参数中指定了无效的上下文句柄。 与 Schannel SSP 一起使用。
SEC_E_INVALID_TOKEN 缓冲区的类型不正确,或者找不到SECBUFFER_DATA类型的缓冲区。 与 Schannel SSP 一起使用。
SEC_E_MESSAGE_ALTERED 消息已更改。 与 Schannel SSP 一起使用。
SEC_E_OUT_OF_SEQUENCE 未按正确的顺序接收消息。
SEC_I_CONTEXT_EXPIRED 消息发送方已完成使用连接,并已启动关闭。 有关启动或识别关闭的信息,请参阅 关闭 Schannel 连接。 与 Schannel SSP 一起使用。
SEC_I_RENEGOTIATE 远程方需要新的握手序列,或者应用程序刚刚启动关闭。 返回到协商循环并调用 AcceptSecurityContext (Schannel) InitializeSecurityContext (Schannel) ,传递从 DecryptMessage () 返回的SECBUFFER_EXTRA。

备注

有时,应用程序将从远程方读取数据,尝试使用 DecryptMessage (Schannel) 进行解密,并发现 DecryptMessage (Schannel) 成功,但输出缓冲区为空。 这是正常行为,应用程序必须能够处理它。

使用 Schannel SSP 时,当消息发送方关闭连接时, DecryptMessage (General) 函数将返回SEC_I_CONTEXT_EXPIRED。 有关启动或识别关闭的信息,请参阅 关闭 Schannel 连接

如果使用 TLS 1.0,可能需要多次调用此函数,每次调用时调整输入缓冲区,以解密整个消息。

DecryptMessage (Schannel) 函数在收到除应用程序数据以外的握手后 TLS 协议消息时返回SEC_I_RENEGOTIATE。 当 DecryptMessage (Schannel) 函数返回SEC_I_RENEGOTIATE后,任何进一步的 EncryptMessage () 和 DecryptMessage () 调用都将失败并SEC_E_CONTEXT_EXPIRED。 应用程序通过调用 AcceptSecurityContext (Schannel) (服务器端) 或 InitializeSecurityContext (Schannel) (客户端) 并传递从 DecryptMessage () 返回SECBUFFER_EXTRA来处理这种情况。 在此初始调用返回值后,继续操作,就像应用程序正在创建新连接一样。 然后,应用程序可以继续调用 EncryptMessage () 和 DecryptMessage () 。 有关详细信息,请参阅 创建 Schannel 安全上下文

要求

要求
最低受支持的客户端 Windows XP [仅限桌面应用]
最低受支持的服务器 Windows Server 2003 [仅限桌面应用]
标头 Sspi.h (包括 Security.h)
Secur32.lib
DLL Secur32.dll

另请参阅