使用Microsoft安全支持提供程序接口(SSPI)

时间:2017-03-08 16:22:17

标签: c++ encryption digital-signature kerberos sspi

我想在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

----回复Remu​​s Rusanu的答案2017-03-09 ---------------------------

感谢@Remus Rusanu的回答,我还没有考虑GSSAPI互操作性文档。

Here声明" GSS_Wrap和GSS_Unwrap用于完整性和隐私,使用由" conf_flag"的值控制的隐私。 。参数"和#34;相当于GSS_Wrap的SSPI是EncryptMessage(Kerberos),用于完整性和隐私性#34;。

如果协商的上下文需要,那么" EncryptMessage [...]也将进行签名。"。这对我来说,至少需要为InitializeSecurityContext()设置以下fContextReq标志:

  • ISC_REQ_CONFIDENTIALITY
  • ISC_REQ_INTEGRITY

你(或其他人)可以证实这一点吗?

----更新2017-03-16 ------------------------------------- ---------------------------

经过进一步研究后,我想出了以下见解:

  1. 无论Securitycontext的初始化方式如何,Kerberos特定的EncryptMessage()函数都不会提供消息完整性。

    • general EncryptMessage()general DecryptMessage功能支持创建和验证邮件完整性的功能,因为存在一些支持的安全支持提供程序(SSP) - 但Kerberos不支持。

    • 如果DecryptMessage将检查消息的完整性,则在修改消息的情况下必须有相应的错误返回码。一般的DecryptMessage接口列出了错误代码" SEC_E_MESSAGE_ALTERED"被描述为"消息已被更改。与Digest和Schannel SSP一起使用。"。

    • SSP摘要和Schannel的特定DecryptMessage界面列出了SEC_E_MESSAGE_ALTERED - 但Kerberos DecryptMessage

    • 在一般EncryptMessage文档的参数说明中,术语“签名”和#39;仅用于摘要SSP:"使用摘要SSP时,必须有第二个类型的缓冲区 SECBUFFER_PADDING或SEC_BUFFER_DATA用于保存签名信息"。

  2. MakeSignature不会根据Wikipedia's definition创建数字签名(真实性+不可否认性+完整性)。 MakeSignature创建加密哈希以提供消息完整性。

    • MakeSignature()函数的名称导致SSPI创建数字签名(真实性+不可否认性+完整性)的想法,但MakeSignature documentation解释了只创建了加密校验和(提供)完整性):" MakeSignature函数生成消息的加密校验和,还包括排序信息以防止消息丢失或插入。"

    • VerifySignature documentation也有助于澄清SSPI的术语:"验证使用MakeSignature函数签名的邮件是否按正确顺序收到且未被修改。 "

  3. 从(1)和(2)开始,需要调用EncryptData(),然后调用MakeSignature()(用于密文)以实现机密性和完整性。

  4. 希望我的自我回答会在某个时间点帮助某人;)

    如果有人在我的回答中添加或更正,请回复并帮助改进此处收集的信息!

2 个答案:

答案 0 :(得分:0)

如果我没记错的话,您只需拨打EncryptMessage / DecryptMessage,这也会进行签名,如果协商的上下文需要。例如,如果您查看SSPI/Kerberos Interoperability with GSSAPI,则会指出EncryptMessageGSS_UnwrapDecryptMessage对与GSS_Wrap配对,配对{ {1}}。链接中的示例还表明,您必须提供 3 SecBuffer结构(MakeSignatureSECBUFFER_TOKENSECBUFFER_DATA,我认为是最后一个可选)到{{ 1}}和2 SECBUFFER_PADDINGUsing SSPI with a Windows Sockets ServerUsing SSPI with a Windows Sockets Client上的两个补充示例提供了完整的功能消息交换,您还可以看到永远不会调用EncryptMessage / DecryptMessage,签名由Encrypt / Decrypt处理并放置在'安全令牌'标题或预告片中(SSPI / SPNego / Kerberos未指定它在线上的位置,这不是TLS / Schannel ...)。

答案 1 :(得分:0)

如果您想创建仅带有签名(未加密)的 GSS Wrap 令牌,请将 KERB_WRAP_NO_ENCRYPT 作为 qop 值传递给 EncryptMessage。签名的包装令牌包括有效负载和签名。

MakeSignature 创建一个 GSS MIC 令牌 - 是签名,不包括有效负载。您可以将此用于需要分离签名的应用协议。