【问题标题】:Encrypt and sign a message using Microsoft Security Support Provider Interface (SSPI)使用 Microsoft 安全支持提供程序接口 (SSPI) 对消息进行加密和签名
【发布时间】: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 更新 ------------------------- --------------------------

经过进一步研究,我得出以下见解:

  1. 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 来保存签名信息”。

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

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

    • VerifySignature documentation 还有助于澄清 SSPI 的术语:“验证使用 MakeSignature 函数签名的消息是否以正确的顺序收到并且未被修改。”

  3. 从 (1) 和 (2) 可以看出,需要调用 EncryptData() 和之后的 MakeSignature()(用于密文)以实现机密性和完整性。

希望我的自我回答能在某个时间点对某人有所帮助;)

如果有人对我的回答有什么要补充或更正的,请回复并帮助改进此处收集的信息!

【问题讨论】:

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


    【解决方案1】:

    如果我没记错的话,你只打电话给EncryptMessage/DecryptMessage,这也会进行签名,如果协商的上下文需要它。例如,如果您查看SSPI/Kerberos Interoperability with GSSAPI,它表明EncryptMessagepairs 与GSS_UnwrapDecryptMessageGSS_Wrap 配对,没有 涉及MakeSignature。链接中的示例还显示您必须为EncryptMessage 提供 3 SecBuffer 结构(SECBUFFER_TOKENSECBUFFER_DATASECBUFFER_PADDING,我认为最后一个是可选的)和 2 为@987654335 @。 Using SSPI with a Windows Sockets ServerUsing SSPI with a Windows Sockets Client 的两个互补示例提供了完整的功能消息交换,您还可以看到 MakeSignature/VerifySignature 从未被调用,签名由加密/解密处理并放置在“安全令牌”中' 标头或尾标(SSPI/SPNego/Kerberos 未指定它在线路上的位置,这不是 TLS/Schannel...)。

    【讨论】:

    • 感谢您的回答。请查看我修改后的问题以进行跟进
    • 没错,传递适当的ISC_REQ_XXX 是设置上下文的方法,以便EncryptMessage 做“正确”的事情。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2014-05-31
      • 2011-04-01
      • 2011-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多