【发布时间】:2017-03-08 16:22:17
【问题描述】:
我想在 Windows 域环境(使用 Kerberos)中使用 Microsoft 的安全支持提供程序接口 (SSPI) 在两个实体之间(使用 C++)发送加密和签名的消息。
根据 MSDN 中的文档,有两个函数 MakeSignature() 和 EncryptMessage() [1] 但文档以及示例代码 [2] 没有明确回答如何发送加密数据的问题和签名(根据 encrypt-than-mac)。
谁能确认我必须按顺序手动调用 EncryptMessage() 和 MakeSignature() 才能获得所需的结果?还是我错过了什么,而 EncryptMessage() 有办法直接创建加密数据的签名?
[1] EncryptMessage() 和 MakeSignature() 的 MSDN 文档 https://msdn.microsoft.com/en-us/library/windows/desktop/aa378736(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375378(v=vs.85).aspx
[2] MSDN 示例代码 https://msdn.microsoft.com/en-us/library/windows/desktop/aa380531(v=vs.85).aspx
---- 回复 Remus Rusanu 的回答 2017-03-09 ---------------------------
感谢@Remus Rusanu 的回答,我还没有考虑到 GSSAPI 互操作性文档。
Here 声明“GSS_Wrap 和 GSS_Unwrap 用于完整性和隐私,使用由“conf_flag”参数的值控制的隐私。”并且“与 GSS_Wrap 等效的 SSPI 是 EncryptMessage (Kerberos) 以确保完整性和隐私性”。
您说过“如果协商的上下文需要,EncryptMessage [...] 也会进行签名。”。这对我来说意味着,至少需要为 InitializeSecurityContext() 设置以下 fContextReq 标志:
- ISC_REQ_CONFIDENTIALITY
- ISC_REQ_INTEGRITY
您(或其他人)可以确认吗?
---- 2017-03-16 更新 ------------------------- --------------------------
经过进一步研究,我得出以下见解:
-
Kerberos 特定的 EncryptMessage() 函数不提供消息完整性,无论 Securitycontext 是如何初始化的。
general EncryptMessage() 和 general DecryptMessage 函数支持创建和验证消息完整性的功能,因为存在一些支持的安全支持提供程序 (SSP) - 但 Kerberos 不支持。
如果 DecryptMessage 会检查消息的完整性,则在消息被修改的情况下必须有相应的错误返回代码。通用 DecryptMessage 接口列出了错误代码“SEC_E_MESSAGE_ALTERED”,描述为“消息已被更改。与 Digest 和 Schannel SSP 一起使用。”。
SSP Digest 和 Schannel 的特定 DecryptMessage 接口列出了 SEC_E_MESSAGE_ALTERED - 但 Kerberos DecryptMessage 没有。
在通用 EncryptMessage 文档的参数描述中,术语“签名”仅用于摘要 SSP:“使用摘要 SSP 时,必须有第二个缓冲区类型 SECBUFFER_PADDING 或 SEC_BUFFER_DATA 来保存签名信息”。
-
MakeSignature 不会根据Wikipedia's definition(真实性+不可否认性+完整性)创建数字签名。 MakeSignature 创建加密哈希以提供消息完整性。
MakeSignature() 函数的名称导致 SSPI 创建数字签名(真实性 + 不可否认性 + 完整性)的想法,但 MakeSignature documentation 解释说仅创建加密校验和(提供完整性) :“MakeSignature 函数生成消息的加密校验和,还包括排序信息以防止消息丢失或插入。”
VerifySignature documentation 还有助于澄清 SSPI 的术语:“验证使用 MakeSignature 函数签名的消息是否以正确的顺序收到并且未被修改。”
从 (1) 和 (2) 可以看出,需要调用 EncryptData() 和之后的 MakeSignature()(用于密文)以实现机密性和完整性。
希望我的自我回答能在某个时间点对某人有所帮助;)
如果有人对我的回答有什么要补充或更正的,请回复并帮助改进此处收集的信息!
【问题讨论】:
标签: c++ encryption digital-signature kerberos sspi