DecryptMessage (Schannel) 函数解密消息。 某些包不会加密和解密消息,而是执行并检查完整性 哈希。
将此函数与 Schannel 安全支持提供程序 (SSP)一起使用,以向消息发送方发出请求,请求重新协商连接属性或关闭连接。
注释
如果一个线程正在加密,另一个线程正在解密,则可以同时从单个安全支持提供程序接口 (SSPI) 上下文中的两个不同的线程调用 EncryptMessage (Schannel) 和 DecryptMessage (Schannel)。 如果多个线程正在加密,或者多个线程正在解密,则每个线程应获取唯一的上下文。
语法
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 类型设置为SECBUFFER_TOKEN。 |
注解
有时,应用程序从远程方读取数据,尝试使用 DecryptMessage(Schannel)对其进行解密,并发现 DecryptMessage(Schannel) 成功,但输出缓冲区为空。 此行为是正常的,应用程序必须能够处理它。
使用 Schannel SSP 时,当消息发送方关闭连接时, DecryptMessage (常规) 函数将返回SEC_I_CONTEXT_EXPIRED。 有关启动或识别关闭的信息,请参阅 关闭 Schannel 连接。
如果使用 TLS 1.0,则可能需要多次调用此函数,调整每次调用的输入缓冲区,以解密整个消息。
当解密消息(Schannel)函数收到除应用程序数据以外的后握手 TLS 协议消息时,它将返回SEC_I_RENEGOTIATE。
当 DecryptMessage (Schannel) 返回SEC_I_RENEGOTIATE后,任何进一步的 EncryptMessage() 和 DecryptMessage() 调用将失败并SEC_E_CONTEXT_EXPIRED。 应用程序通过调用 SECBUFFER_EXTRA 缓冲区 SEC_I_RENEGOTIATE 。 此初始调用返回一个值后,继续作,就像应用程序正在创建新连接一样。 然后,应用程序可以继续调用 EncryptMessage() 和 DecryptMessage()。 有关详细信息,请参阅 创建 Schannel 安全上下文。
要求
| 要求 | 价值 |
|---|---|
| 支持的最低客户端 | Windows XP [仅限桌面应用] |
| 支持的最低服务器 | Windows Server 2003 [仅限桌面应用] |
| 标题 | Sspi.h(包括 Security.h) |
| 图书馆 | Secur32.lib |
| DLL | Secur32.dll |