使用SSL通配符证书验证主机
Validating a host using SSL Wildcard certificates
我的HTTPS客户端使用Poco C++与我们的服务器连接,该服务器使用通配符证书(*.example.com
(。连接失败,出现CertificateValidationException
,错误消息为"来自x.y.z.w的证书不可接受:应用程序验证失败">。
奇怪的是,它并不总是失败,只是在大多数时候。经过大量调试,我的直觉是这与拓扑结构(例如,跨子网(或主机名如何/何时转换为IP地址有关。
我认为这是因为在一切正常的情况下,本地DNS会路由主机名。但在它不起作用的情况下(上面的错误消息(,主机名翻译在本地盒子上,比如我的电脑
有没有办法缩小范围?这是常见的还是已知的问题?
谢谢。
我自己也遇到了同样的症状。使用Poco::Net::HTTPSClientSession,我可以很好地连接到非通配符站点,但在连接到*.example.com通配符站点时失败,出现上面提到的异常和消息。然而,请注意,我观察到的行为是100%一致的,从不间断。
在通过Poco源代码进行调试后,我发现HTTPSClientConnection类如何设置自己来执行证书验证存在问题。我在pocoproject.org上提交了Poco问题#1303,但问题是,如果您使用无arg构造函数创建HTTPSClientSession,当使用通配符证书连接到服务器时,您总是会遇到此异常。例如:
Poco::URI uri("http://blah.example.com"); // SSL cert is for *.example.com
Poco::Net::HTTPSClientSession session; // Note no-arg constructor
session.setHost(uri.getHost());
session.setPort(uri.getPort());
Poco::Net::HTTPRequest req;
// Populate req...
session.sendRequest(req); // Throws CertificateValidationException:
// "Unacceptable certificate from x.x.x.x,
// application verification failure"
问题是,在验证证书时,如果主机名尚未设置,各种Poco::Net类会将对等名称查找为IP地址,然后尝试将该IP地址与通配符证书CN匹配(显然,x.y.z.w将无法与*.example.com匹配(。
好消息是有几个简单的解决办法。最简单的方法是只使用HTTPSClientSession(主机,端口(构造函数,它将在底层SecureStreamSocket上设置正确的主机名,以便后续的证书验证将真实的主机名(blah.example.com(与证书(CN=*.example.com(相匹配,而不是IP地址:
Poco::URI uri("http://blah.example.com");
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); // Calls SecureStreamSocket::setPeerHostName() internally
还有其他解决方法:首先创建自己的SecureStreamSocket,对其调用setPeerHostName((,然后将其传递到相应的HTTPSClientSession构造函数中,等等。如果需要,请参阅上面的问题跟踪器链接以获取更多想法。
- 正在尝试了解输入验证循环
- 如何在C++中检查2D数组中负值的输入验证
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- LibGit2 SSH身份验证失败
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- constexpr上下文中std::initializer_list的验证
- 正在验证c++中用户的整数输入
- 加密++验证大文件签名
- C++卡验证问题
- 验证指针链
- 此代码验证公式是什么意思?
- cin 的十进制输入验证?
- 如何停止 CLR 主机?
- 简单的 HTML 验证器
- 模拟的 HTTP 身份验证仅在本地主机上工作
- 如何使用OpenSSL 1.1.0验证主机名
- Boost、asio、https 和主机/证书验证
- 使用SSL通配符证书验证主机
- 在连接(ping)之前验证IP地址(主机)是否存在