1

我有一个简单的客户端套接字应用程序,我想通过它访问网站。为了访问 Internet,我的客户端必须通过 HTTP 代理服务器(我使用的是 Microsoft Forefront 威胁管理网关)。代理服务器需要身份验证,并且被配置为通过 GSSAPI 接受 Kerberos。

在我的客户端中,我使用 Microsoft 的 SSPI:

首先,我调用AcquireCredentialsHandle成功并返回SEC_E_OK

接下来,我调用InitializeSecurityContext也成功并返回SEC_E_OK

到目前为止,一切都很好。但是现在,我需要将令牌提交给代理服务器进行授权,这是给我带来问题的部分。

如果我使用 Internet Explorer 连接到我的代理服务器,我可以通过 Wireshark 观看数据包交换。IE 与 Kerberos 协商票证,并似乎通过 Proxy-Authorization 标头提交票证。标头内容似乎是 base64 编码的。

如果我只是获取从返回的令牌InitializeSecurityContext,base64 对其进行编码并通过类似的标头将结果发送到代理服务器Proxy-Authorization: Negotiate <base64Data>,则身份验证失败。

我觉得我很接近,但仍然缺少一些东西。一个站点讨论了在发送之前在令牌上使用 EncryptMessage。另一个讨论了使用相互身份验证(我不认为 IE 正在使用相互身份验证,因为客户端似乎只发送一次授权,并且没有来自服务器的反馈数据(InitializeSecurityContext第二次调用)另一个站点概述了将令牌与不同的SEC_BUFFER类型(填充、数据等)和加密。我怀疑这是我需要做的,因为我没有找到太多关于如何做的文档。

您可能有任何见解或建议将不胜感激。

2014 年 7 月 19 日更新:为了清楚起见,我在问如何使用 SSPI 来计算“base64Data”字段(如上所述)。虽然计算 SECBUFFER_TOKEN 缓冲区中包含的内容的 base64 编码是我最初的猜测,但服务器不接受结果,因此它显然是无效的。

进一步的研究表明,令牌必须“包装”(又名“EncryptMessage”通过 SSPI)并以与 GSSAPI 兼容的方式加密,必须使用三个缓冲区(按顺序:SECBUFFER_TOKEN、SECBUFFER_DATA 和 SECBUFFER_PADDING)我试过这个昨天,但没有找到成功。

http://msdn.microsoft.com/en-us/library/ms995352.aspx

http://msdn.microsoft.com/en-us/magazine/cc301890.aspx

4

1 回答 1

0

您真的想自己编写代理交互代码吗?我宁愿推荐libcurl在 Windows 上使用。这在工作中与 TMG 配合得很好。

您的复制和粘贴失败的原因是接受检测到您重新发送作为回复。Kerberos 是防重放的。你不能偷一张票并重新使用它。

考虑您已经调用InitializeSecurityContext并在成功调用时接收到SEC_E_OK指向 a 的指针SecBufferDesc。您必须访问包含的数组,读取PSecBuffer结构,访问pvBuffer元素并将转换为 a 的内容传递void*给将(十六进制字节)转换为 base64 为 aunsigned char*的函数。不要忘记传递长度。那你不。这是 HTTP 代理的 base64 编码票证。unsigned char*char*cbBuffer

您可以使用EncryptMessage但不能与 HTTP 一起使用。HTTP 使用 TLS。如果要使用EncryptMessage,请使用普通套接字。EncryptMessage将透明地加密您的客户端和服务器之间的整个流量。

顺便说一句:代理会向 IE 返回一张票,因为我总是询问相互身份验证。你应该做这个案子。因此,您必须查看 init 上下文,直到收到OK而不是CONTINUE_NEEDED.

于 2014-07-18T06:48:50.680 回答