【发布时间】:2014-09-27 07:25:49
【问题描述】:
是否可以使用 Win32 WinHTTP API 实现证书固定,如果可以,如何实现? IE。如何检查返回的服务器证书与“已知良好”的证书,最好不必将证书永久写入本地证书存储区。
【问题讨论】:
是否可以使用 Win32 WinHTTP API 实现证书固定,如果可以,如何实现? IE。如何检查返回的服务器证书与“已知良好”的证书,最好不必将证书永久写入本地证书存储区。
【问题讨论】:
是否可以使用 Win32 WinHTTP API 实现证书锁定,如果可以,如何实现?
看起来您可以固定证书。您可以使用WINHTTP_STATUS_CALLBACK 设置回调。当使用WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 调用回调时,您可以使用WinHttpQueryOption 和WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT 检查证书。服务器证书以WINHTTP_CERTIFICATE_INFO 结构返回。
SSL in WinHTTP 有一个页面提供更多信息。
...无需将证书永久写入本地证书存储区。
证书存储的问题是另一个机构可能声称对您正在连接的站点进行认证。在这种情况下,真正的受信任的权威甚至不需要在商店中就可以得到 pwn'd。这是网络应用程序/浏览器安全模型和 CA Zoo 的 [明显] 问题之一。
【讨论】:
(受 jww 的回答启发)
首先,我发现this page 是关于固定以及证书和公钥固定之间选择的优秀背景资料。
我使用 WinHTTP API 实现了证书锁定,如下所示:
在 WinHttpOpen 之后 WinHttpConnect 之前,设置发送请求时的回调:
WinHttpSetStatusCallback(hSession, &callbackFunc, WINHTTP_CALLBACK_SENDING_REQUEST, NULL);
在回调函数中,检索原始证书 blob:
PCCERT_CONTEXT pCert=NULL;
DWORD dwSize=sizeof(pCert);
WinHttpQueryOption(hInternet, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCert, &dwSize);
如果进行完整的证书固定,请将 sha1(pCert->pbCertEncoded) 与已知良好的证书 SHA1 指纹进行比较。
-或者- 如果改为使用公钥固定,请将 sha1(pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData) 与服务器公钥的已知良好 SHA1 进行比较。
【讨论】:
CryptEncodeObject(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, ...) 获得此信息。顺便说一句,WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 现在似乎也已被弃用,没有明显的替代品可用:-(
CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, thumbprint, &thumbprint_size) 获取指纹,即 SHA1 哈希。