39

对于我的应用程序 Transdroid,我通过 HTTP 连接到远程服务器,也可以通过 HTTPS 安全连接。对于与 HttpClient 的这些 HTTPS 连接,我使用自定义 SSL 套接字工厂实现来确保自签名证书正常工作。基本上,我接受一切并忽略对任何证书的每次检查。

这已经有一段时间了,但它不再适用于 Android 2.2 FroYo。尝试连接时,会返回异常:

java.io.IOException: SSL handshake failure: I/O error during system call, Broken pipe

这是我初始化 HttpClient 的方式:

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", new PlainSocketFactory(), 80));
    registry.register(new Scheme("https", (trustAll ? new FakeSocketFactory() : SSLSocketFactory.getSocketFactory()), 443));
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);

我使用了 FakeSocketFactory 和 FakeTrustManager,其来源可以在这里找到。

同样,我不明白为什么它突然停止工作,甚至不明白错误“Broken pipe”是什么意思。我在 Twitter 上看到消息说 Seesmic 和 Twidroid 在 FroYo 上启用 SSL 时也会失败,但我不确定它是否相关。

感谢您的任何指示/帮助!

4

2 回答 2

43

这是答案,非常感谢愿意分享修复的有用的 Seesmic 开发人员:

在自定义套接字工厂中,套接字创建(带有createSocket)显然已专门针对SSLSocketFactory实现进行了更改。所以老:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket();
    }

需要改为:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
    }

然后它又对我有用了!

更新:由于这仍然是一个流行的答案,让我更新我的工作代码链接。这个支持 SSL 的套接字工厂支持现代协议 (TLS 1.1+)、SNI 并可选择允许接受所有证书(不安全,忽略所有 SSL 证书)或自签名证书(通过 SHA-1 哈希)。

于 2010-05-25T15:57:00.533 回答
1

有关此问题的更多信息 http://code.google.com/p/android/issues/detail?id=10472 这解决了我们更新到 Android 2.2 时 HTC Desire 的 SSL 问题

于 2010-09-02T18:05:53.990 回答