使用WinHTTP API锁定证书

是否可以使用Win32 WinHTTP API实现证书固定,如果是,如何实现? 即,我如何根据“已知良好”证书检查返回的服务器证书,最好不必将证书永久写入本地证书存储区。

是否可以使用Win32 WinHTTP API实现证书固定,如果是,如何实现?

看起来你可以固定证书。 您可以使用WINHTTP_STATUS_CALLBACK设置回调。 使用WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER调用回调时,可以使用WinHttpQueryOptionWINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT检查证书。 服务器证书以WINHTTP_CERTIFICATE_INFO结构返回。

WinHTTP中的SSL页面提供了更多信息。


…无需将证书永久写入本地证书存储区。

证书存储的问题是另一个权威机构声称可以certificate您要连接的站点。 在这种情况下, 真正的可信任权限甚至不需要在商店中进行pwn’d。 这是Web应用程序/浏览器安全模型和CA Zoo的[明显]问题之一。

(灵感来自jww的回答)

首先,我发现这个页面是关于固定和证书与公钥固定之间选择的优秀背景阅读。

我使用WinHTTP API实现了证书固定,如下所示:

  1. 在WinHttpOpen之后但在WinHttpConnect之前,为发送请求时设置回调:

    WinHttpSetStatusCallback(hSession, &callbackFunc, WINHTTP_CALLBACK_SENDING_REQUEST, NULL);

  2. 在回调函数中,检索原始证书blob:

    PCCERT_CONTEXT pCert=NULL; DWORD dwSize=sizeof(pCert); WinHttpQueryOption(hInternet, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCert, &dwSize);

  3. 然后,如果执行完整证书固定, sha1(pCert->pbCertEncoded)与已知的良好证书SHA1指纹进行比较。

  4. – 或者 – 如果执行公钥固定, sha1(pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)与服务器公钥的已知良好SHA1进行比较。