使用 Schannel 的 DTLS

DTLS using Schannel

我正在尝试使用 Windows 下的 Schannel 创建 DTLS "connection"(我正在最近的 Windows 10 版本下进行测试,因此 Schannel 支持的所有 DTLS 版本都应该可用)

我尝试按照文档从工作代码开始建立常规 TLS 连接:

  1. InitializeSecurityContext 在第一次传递时使用空输入,SECBUFFER_TOKEN & SECBUFFER_ALERT 在输出时
  2. AcceptSecurityContext,输入为 SECBUFFER_TOKEN & SECBUFFER_EMPTY,输出为 SECBUFFER_TOKEN & SECBUFFER_ALERT。
  3. 重复这两个步骤直到成功,然后继续使用Encrypt/DecryptMessage

这在流模式下工作得很好 (ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM)

如果我尝试用 ISC/ASC_REQ_DATAGRAM 替换 STREAM,我的 InitializeSecurityContext 按预期成功 SEC_I_CONTINUE_NEEDED,但我的第一个 AcceptSecurityContext 然后失败 SEC_E_INVALID_PARAMETER。

我已经尝试将 SCHANNEL_CRED 的 grbitEnabledProtocols 设置为 0 以使用双方记录的默认值,我也尝试将其设置为 SP_PROT_DTLS1_X,但我仍然得到无效参数 return 来自我的第一个 ASC。为了以防万一,我也尝试了 DTLS_1_0 常量。

此外,在我的注册表设置中默认启用所有安全协议。

根据我对 DTLS RFC 的理解,我的代码在 HelloVerifyRequest 步骤失败,而且,根据我对 RFC 的理解,这部分要求安全提供程序从 ClientHello 消息的几个部分生成 cookie以及来源的 IP 地址。但是,我找不到任何将此信息传递给 ASC 函数的记录方式。

(我想?:))我已经在整个互联网上搜索了在 Schannel 下使用 DTLS 的任何工作示例,但没有任何运气。在 Whosebug 上,我发现这个问题只是提到它 is 受支持: Is DTLS supported by Schannel on Windows 7?,链接的 MSDN 文章只是一个高级概述。

我搜索了与此功能相关的常量的任何用法...我搜索了与此相关的常量的任何用法(ISC_REQ_DATAGRAM,SP_PROT_DTLS*,SECBUFFER_DTLS_MTU, ...) 而在我能想到的所有搜索引擎上我唯一能找到的是 sspi.h 的副本或索引 Windows [=70= 中常量的站点]...

我知道其他实现(OpenSSL 等)很好地支持 DTLS,但我真的更愿意继续使用 Schannel,因为我的代码的其他部分目前在 TLS 模式下与 Schannel 一起工作得很好。

来自微软: 没有使用 Schannel 实现 DTLS 的文档。已知和持续的文档差距。

存在一些差异,但 TLS 客户端或服务器可以相当容易地适应 DTLS(许多客户已成功做到这一点)。

  1. 将 SCHANNEL_CRED.grbitEnabledProtocols 设置为 SP_PROT_DTLS1_X。
  2. 调用AcceptSecurityContext时,通过SECBUFFER_EXTRA传递客户端的SOCKADDR。
  3. MTU 可以通过 SetContextAttributes 使用常量 SECPKG_ATTR_DTLS_MTU 设置,其中缓冲区只是一个指向 ULONG 的指针。 [默认为 1096 字节。]
  4. 当 ISC/ASC return SEC_I_MESSAGE_FRAGMENT 时,发送此片段并在循环中再次调用 ISC/ASC 以获取下一个片段(不尝试从中读取数据网络)。
  5. 在您的应用程序中实现超时和重传逻辑(因为 schannel 不拥有套接字)。
  6. 接收片段时,schannel 将尝试消除 如果可能,重复、重新排序和重新assemble。
  7. SCHANNEL_SHUTDOWN 适用于 DTLS。

您可以使用 https://github.com/mobius-software-ltd/iotbroker.cloud-windows-client 作为在 windows 上实施 DTLS 的示例 它不使用 SChannel,而是使用 netty 库。 MQTT-SN 和 CoAP 都在这个项目下支持 DTLS。 BR 尤连奥法