Android Paho SSL,带有服务器发送的CA证书,包括主机名验证

Android Paho SSL,带有服务器发送的CA证书,包括主机名验证,android,ssl,mqtt,paho,Android,Ssl,Mqtt,Paho,复制:有几个类似的问题(,) 对我的问题没有合适的答案。我试图给出一个具体的背景(例如泛美卫生组织和具体的测试地点)和问题 主要问题:我使用安卓Paho作为客户端,一切正常。现在我想添加SSL连接。代理是认证实体,在握手期间发送其CA颁发的证书。 (请注意,我是一名安全新手,我刚刚阅读了一些有关该主题的教程。) 我能找到的大多数Java和Paho示例都涉及本地证书(自行颁发的或不太知名的CA等),而我需要在握手期间管理代理服务器发送到我的应用程序的CA颁发的证书 从Android文档()来看,您

复制:有几个类似的问题(,) 对我的问题没有合适的答案。我试图给出一个具体的背景(例如泛美卫生组织和具体的测试地点)和问题

主要问题:我使用安卓Paho作为客户端,一切正常。现在我想添加SSL连接。代理是认证实体,在握手期间发送其CA颁发的证书。 (请注意,我是一名安全新手,我刚刚阅读了一些有关该主题的教程。)

我能找到的大多数Java和Paho示例都涉及本地证书(自行颁发的或不太知名的CA等),而我需要在握手期间管理代理服务器发送到我的应用程序的CA颁发的证书

从Android文档()来看,您似乎只需要使用
SSLSocketFactory.getDefault()
,因为系统中包含了知名CA的根CA认证。因此,简单地说:

MqttConnectOptions options;

// ...

options.setSocketFactory(SSLSocketFactory.getDefault());
但我在这两方面都做了测试:

  • ssl://iot.eclipse.org:8883
  • ssl://test.mosquitto.org:8883
我总是得到可怕的
javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:Trust-anchor for certification path not found.

上述android文档和堆栈溢出答案给出的可能原因可能不适用于此类知名和使用过的测试站点。我假设这两个站点都更新了由知名认证机构颁发的证书,在链中没有不太知名的CA。(虽然我找不到明确的证据,但网络上的使用示例似乎确实暗示了这一点。)

有什么建议吗?我真的不知道从这里走到哪里(我想我错过了一些明显的东西,但没有明确说明。)

次要问题:此外,Android文档警告说,
SSLSocket
不会进行任何主机名验证:

因此它建议:

SocketFactory sf = SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) sf.createSocket("gmail.com", 443);
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
SSLSession s = socket.getSession();

// Verify that the certicate hostname is for mail.google.com
// This is due to lack of SNI support in the current SSLSocket.
if (!hv.verify("mail.google.com", s)) {
    throw new SSLHandshakeException("Expected mail.google.com, "
                                    "found " + s.getPeerPrincipal());
}
请注意,您需要对实际套接字的引用才能传递到
verify()
(没有重载选项),您不能只配置
SSLSocketFactory

Paho似乎没有公开对其使用的套接字的访问,也没有设置自定义验证器。您只能设置
SSLSocketFactory

如果我理解正确,似乎有一个泛美卫生组织的错误报告:

实际上是同一个问题吗

最后,如果是这样的话,有没有办法解决这个问题,让Android Paho通过SSL进行主机名验证

编辑部分答案/调查结果:我在这里记录我的部分临时调查结果

我对
iot.eclipse.org:8883
test.mosquitto.org:8883
的假设似乎是错误的:我发现这两个文档都提供了客户端显式使用的证书(我假设是自签名的,没有指定)。有些例子忽略了这一点,使我产生了误解

  • ssl://iot.eclipse.org:8883 :如
  • ssl://test.mosquitto.org:8883 :如

在自定义的信任管理器中加载证书,一切正常。谜团就此解开。我们自己的具有CA证书的代理尚未准备好进行测试。

iot.eclipse.org:8883使用自签名证书。test.mosquitcho.org:8883使用由自定义mosquitcho.org CA颁发的证书,因此等同于自签名证书。如何处理证书更新?我的意思是,“在自定义TrustManager中加载证书”意味着您必须将.crt文件放入包中。