安卓2.2 FroYo上的自定义SSL处理停止工作

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时失败的消息,但不确定是否相关。

感谢任何指导/帮助!

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哈希)。


我曾经碰到了同样的问题。非常感谢这个快速、简单的解决方案。 - Ulrich Scheller
这个修复方法本身并没有解决我的问题 - 我发现我还需要增加建立套接字连接的线程的优先级到THREAD_PRIORITY_URGENT_AUDIO(在连接建立后将优先级设置回THREAD_PRIORITY_MORE_FAVORABLE)。在这种特定情况下,我怀疑动画使用了太多的CPU资源 :-( - tonys
我仍然遇到了SSL握手失败的问题:在系统调用过程中发生I/O错误,未知错误:0。 - Mikey
如何在活动中调用上述函数? - Kikki

1

具体来说,请查看评论#17:http://code.google.com/p/android/issues/detail?id=10807#c17。这在我准备好一个Android应用程序时帮了我很大的忙。 - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接