我想在Windows域环境(使用Kerberos)中使用Microsoft的安全支持提供程序接口(SSPI)在两个实体之间(在C ++中)发送加密和签名的消息。
根据MSDN中的文档,有两个函数MakeSignature()和EncryptMessage()[1],但是文档以及示例代码[2]并未明确解决如何发送经过加密和签名的数据的问题(根据crypto-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”,其描述为“消息已更改。与摘要和Schannel SSP一起使用。”。
SSP摘要和Schannel的特定DecryptMessage接口列出了SEC_E_MESSAGE_ALTERED-但Kerberos DecryptMessage没有。
在EncryptMessage常规文档的参数描述中,术语“签名”仅用于Digest SSP:“使用Digest SSP时,必须有第二个类型的缓冲区
SECBUFFER_PADDING或SEC_BUFFER_DATA来保存签名信息”。
MakeSignature不会根据Wikipedia's definition(真实性+不可否认性+完整性)创建数字签名。 MakeSignature创建一个加密哈希以提供消息完整性。
MakeSignature()函数的名称引出了一个想法,即SSPI创建了数字签名(真实性+不可否认性+完整性),但是MakeSignature documentation解释说仅创建了加密校验和(提供完整性):“ MakeSignature函数生成消息的密码校验和,还包括排序信息,以防止消息丢失或插入。”
VerifySignature documentation也有助于阐明SSPI的术语:“验证使用MakeSignature函数签名的消息是否以正确的顺序被接收并且未被修改。”
从(1)和(2)可以看出,需要调用EncryptData(),然后调用MakeSignature()(用于密文)以实现机密性和完整性。
希望我的自我解答会在某个时候帮助某人;)
如果有人在我的回答中有补充或纠正的内容,请答复并帮助改善此处收集的信息!
最佳答案
如果我没记错的话,您只能调用EncryptMessage
/ DecryptMessage
,并且如果协商的上下文需要它,也可以执行签名。例如,如果您查看SSPI/Kerberos Interoperability with GSSAPI,它将指出与EncryptMessage
成对的GSS_Unwrap
对和与DecryptMessage
成对的GSS_Wrap
对,而不涉及MakeSignature
。链接中的示例还显示,必须为SECBUFFER_TOKEN
提供3个SecBuffer结构(SECBUFFER_DATA
,SECBUFFER_PADDING
和EncryptMessage
,我认为最后一个是可选的),为DecryptMessage
提供2个。 Using SSPI with a Windows Sockets Server和Using SSPI with a Windows Sockets Client的两个互补示例提供了完整的功能消息交换,您还可以看到从未调用MakeSignature
/ VerifySignature
,签名由Encrypt / Decrypt处理,并放置在“安全令牌”中标题或尾部(SSPI / SPNego / Kerberos并未指定连接的头或尾,这不是TLS / Schannel ...)。
关于c++ - 使用Microsoft安全支持提供程序接口(interface)(SSPI)加密和签名消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42676575/