在 WinINet 中手动验证服务器证书

2023-12-01

我正在尝试对 WinINet 客户端实施手动自签名 SSL 证书验证。我试图通过打电话来接近它InternetQueryOption with INTERNET_OPTION_SECURITY_CERTIFICATE or INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT参数,但都返回服务器证书的一些内部解释,没有一个允许访问原始证书公钥或至少是thumbprimnt。

我该如何验证证书?...


除了之前的答案。 如果您想手动检查不受信任的根证书(例如自签名),您需要

  1. 设置标志以忽略不受信任的证书
// Open request before
HINTERNET hRequest = HttpOpenRequest(hConnect, _T("POST"), action, NULL, NULL, NULL, dwFlags, 0);
if (!hRequest) return GetLastError();

// set ignore options to request
DWORD dwFlags;
DWORD dwBuffLen = sizeof(dwFlags);
InternetQueryOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &dwBuffLen);
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
InternetSetOption (hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));
  1. 发送数据请求
if (HttpSendRequest(hRequest, strHeaders, strHeaders.GetLength(), data, len)) {
  1. 只有在数据请求返回后我们才能查看证书信息并检查指纹。 要获取指纹,我们必须使用 cryptapi 中的方法, 所以需要#include“WinCrypt.h”并将crypt32.lib添加到链接器
PCCERT_CHAIN_CONTEXT CertCtx=NULL;
DWORD cbCertSize = sizeof(&CertCtx);

// Get certificate chain information
if (InternetQueryOption(hRequest, INTERNET_OPTION_SERVER_CERT_CHAIN_CONTEXT, (LPVOID)&CertCtx, &cbCertSize))
{
    PCCERT_CHAIN_CONTEXT pChainContext=CertCtx;

    CERT_SIMPLE_CHAIN *simpleCertificateChainWithinContext = NULL;
    for (int i=0; i<pChainContext->cChain; i++)
    {
        simpleCertificateChainWithinContext=pChainContext->rgpChain[i];
        
        // We can check any certificates from chain, but if selfsigned it will be single
        for (int simpleCertChainIndex = 0; simpleCertChainIndex < simpleCertificateChainWithinContext->cElement; simpleCertChainIndex++)
        {
            // get the CertContext from the array
            PCCERT_CONTEXT pCertContext = simpleCertificateChainWithinContext->rgpElement[simpleCertChainIndex]->pCertContext;
            
            // Public key can be getted from
            //  (((*((*pCertContext).pCertInfo)).SubjectPublicKeyInfo).PublicKey).pbData
            // but better to use thumbprint to check

            // CERT_HASH_PROP_ID - is a thumbprint
            BYTE thumbprint[1024];
            DWORD len = 1024;
            if (CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, thumbprint, &len)) {
                //
                // !!! HERE WE CAN CHECK THUMPRINT WITH TRUSTED(PREVIOUSLY SAVED)
                // and return error, or accept request output.
                //
            }
        }
    }
    
    // important! Free the CertCtx
    CertFreeCertificateChain(CertCtx);
}
  1. 为什么要使用指纹来比对证书? 证书中有三个有趣的字段需要比较: 序列号、公钥、指纹。 序列号只是颁发证书的 CA 选择的唯一编号, 公钥很好的解决方案,但指纹是通过完整证书计算的哈希值 (https://security.stackexchange.com/questions/35691/what-is-the-difference- Between-serial-number-and-thumbprint)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 WinINet 中手动验证服务器证书 的相关文章

随机推荐

  • 包含标头时防止出现多个 #define

    来自 python 我对正确的方法有点困惑 我正在尝试将该库包含在我的项目中 https github com nothings stb blob master stb image h 为此 我必须在导入文件之前 define STB IM
  • 如何在 JPA2 中强制使用 @ManyToOne 字段?

    我正在为应用程序设计持久性存储库 我是新来的休眠 JPA2我遇到了麻烦创造更复杂的关系在这种情况下外部强制键 一个例子 只是在记事本上写的 所以不完全是这样 我有一个名为 Person 的顶级类 它可以担任多个职位 另一个类 如果我像这样映
  • 低延迟地从 IP 摄像机获取帧

    我当前正在使用此命令从 RTSP 流获取帧并从标准输出读取帧 ffmpeg nostdin rtsp transport tcp i
  • 如何仅在图像悬停时显示 fancybox 标题

    我正在使用Fancybox插件对于图像库 我想仅当用户将鼠标悬停在图像上时显示图像标题 我不知道要修改代码的哪一部分才能完成此任务 我尝试通过添加来编辑 CSSa hover声明如下 fancybox title over wrap 我什至
  • 将日期对象转换为日历对象[重复]

    这个问题在这里已经有答案了 因此 我从传入对象中获取以下形式的日期属性 Tue May 24 05 05 16 EDT 2011 我正在编写一个简单的辅助方法将其转换为日历方法 我使用以下代码 public static Calendar
  • MySQL Inner Join 有限制吗?

    我有这个查询来收集有关单个订单的信息 它变得非常复杂 我没有任何数据可以测试 所以我问 如果有人在小型和大型数据集中有这方面的经验 那么您可以或应该在单个查询中进行多少个连接是否有限制 将大型查询分成较小的部分是否明智 或者这不会产生重大影
  • 在 Delphi 线程中使用 CoInitialize

    我在 Delphi 程序的线程内使用 TIdHttp 和 TXMLDocument 现在我想知道 这些类是否使用 COM 对象 因此我需要在此线程中调用 CoInitialize 和 CoUninitialize 如果是 我是否必须在执行方
  • Clearcase 问题 [已关闭]

    Closed 这个问题需要调试细节 目前不接受答案 我负责我项目中的clearcase 我没有太多经验 我的问题是 现在我们在 cc 中的项目结构是一个包含 PROD PV ST DV 流的项目 如下所示 链接到屏幕截图 现在 如您所见 我
  • ECMAScript 6 和 ECMAScript Harmony 之间有什么区别?

    我有一段时间认为它们是同一件事 但我经常在博客或答案中看到措辞似乎暗示两者之间存在差异 即使 SO 有两个不同的标签 但它们的描述没有显示出任何明显的区别 我四处搜索了一下 这只增加了混乱 因为似乎我不是唯一一个不确定什么意思的人 这两个术
  • 异步和递归目录扫描,用于 Nodejs 和 Expressjs 中的文件列表

    In this 快递我正在尝试 递归地 获取路由文件中的所有 JSON 文件 data目录 其实我可以控制台日志您可以在其中看到的文件A Mark 但是一旦异步内容完成 我找不到将整组路径发送到视图的方法 一些帮助将非常感激 这是数据 da
  • 有没有办法使用正则表达式来获取第一个单词并替换引用的部分?

    我正在尝试更换相思船 只是复制内容时的占位符 第一个单词 即变量名 SCAFFOLDING new ItemBuilder Material valueOf ACACIA BOAT build SEAGRASS new ItemBuilde
  • 如何向 Winform C# 程序发送 2-3 个参数?

    如何向 Winform C 程序发送 2 3 个参数 例如 我会发送类似的东西MyProg exe 10 20 abc 在我的程序中我可以收到这些值 我不想显示 MyProg exe 它会在后台工作 提前致谢 打开你的Program cs这
  • freemarker 中的数字格式问题 - 在小数后进行舍入

    我正在使用 Freemarker 模板 我有一个十进制值 a 23 65 我只想检索以上值 a 23 6 lt Extract first number after decimal point gt 我使用过 number format e
  • 如何使用 PHP 获取 WAP 中的 MSISDN 号码?

    我开发了一个 WAP 应用程序 我想获取访问我的网站的用户的 MSISDN 我的运营商已将我的 WAP 应用程序列入白名单 我在几部三星手机上成功获得了 MSISDN 但在诺基亚 黑莓和 iPhone 设备上却没有获得相同的结果 请建议我获
  • 在 main() 之外调用函数[重复]

    这个问题在这里已经有答案了 我正在尝试这样做 include
  • cmake include_directories 顺序之后/之前

    我在源树中有一个文件 其名称为 time h 与系统 time h 完全相同 这是无法改变的 我在使用 cmake 时遇到了一个问题 当我使用 include library 选项时 它会被转换为 I 标志 这意味着我的自定义 time h
  • 是在 JavaScript 中更改每个元素的样式的唯一方法吗?

    我一直在研究一些不同的东西 我想使用 JavaScript 来全局调整样式 我想通过更改规定元素样式的 CSS 规则来做到这一点 类似于通过 Webkit 中的检查器执行此操作 但是在来到https developer mozilla or
  • com.google.gson.JsonSyntaxException:应为 BEGIN_ARRAY,但实际为 STRING

    我在解析 json 数据时遇到此错误 Expected BEGIN ARRAY but was STRING at line 1 column 1156 我找不到解决方案 我的 json 数据是 project abbreviation a
  • 使用故事板在两个控制器之间传递数据

    我正在尝试从一个传递数据UITableViewController到另一个 这是我在初始视图控制器中的代码 void tableView UITableView tableView didSelectRowAtIndexPath NSInd
  • 在 WinINet 中手动验证服务器证书

    我正在尝试对 WinINet 客户端实施手动自签名 SSL 证书验证 我试图通过打电话来接近它InternetQueryOption with INTERNET OPTION SECURITY CERTIFICATE or INTERNET