使用SSL通配符证书验证主机

Validating a host using SSL Wildcard certificates

本文关键字:验证 主机 证书 通配符 SSL 使用      更新时间:2023-10-16

我的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构造函数中,等等。如果需要,请参阅上面的问题跟踪器链接以获取更多想法。