1

我有一个在端口 9443 服务的服务器。它使用由 godaddy 为“example.com”签名的 ssl 证书。我尝试连接到如下网址:

https://example.com:9443/api/v1/foo

这在我编写的 ios 应用程序和桌面浏览器中运行良好。如果我尝试从安卓手机连接,我会收到 400 错误请求响应。我通过 chrome for android 尝试了同样的方法,它给了我:

ERR_TUNNEL_CONNECTION_FAILED

服务器也在监听端口 443,使用自签名证书,并且 android 客户端在那里工作正常(我确实需要一些额外的代码来让我的应用程序信任自签名证书)。

在 android 中 https 必须使用端口 443 是否有一些限制?我在想,因为我使用的是合法的 ssl 证书,所以我不需要任何自定义代码来强制应用程序信任证书。我的连接代码:

HttpParams params = new BasicHttpParams();
DefaultHttpClient client = new DefaultHttpClient(params);
HttpResponse response = client.execute(request);
Result result = new Result(response.getStatusLine().getStatusCode());

response.getStatusLine().getStatusCode(); // 400
response.getStatusLine().toString(); // HTTP/1.1 400 Bad Request

谢谢

4

2 回答 2

1

我认为有两种可能。

搜索ERR_TUNNEL_CONNECTION_FAILED android将我带到此页面,作者声称:

由于某些未知原因,Android 不允许您为 SSL 使用非标准端口(即使用 https 时只有端口 443 有效)

我通过在 AT&T 上使用我妻子的 iphone 在端口 2000 上尝试 SSL 网站来确认这一点。果然它工作得很好。所以它不是AT&T。还值得指出的是,它在 wifi 上运行良好。

希望这只是一个错误,将来会修复。

但是,该站点声称通过代理访问站点时会发生错误。您可能在 Android 手机上配置了一个代理,它正试图以某种方式使用它。

判断您所处的世界的最简单方法是使用另一部 Android 手机(如果您有的话)进行检查。

于 2013-10-26T02:26:45.177 回答
0

它可以帮助你

public HttpClient getNewHttpClient() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore
                    .getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory
                    .getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(
                    params, registry);

            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            return new DefaultHttpClient();
        }
    }



public class MySSLSocketFactory extends SSLSocketFactory {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
        super(truststore);

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        sslContext.init(null, new TrustManager[] { tm }, null);
    }

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

    @Override
    public Socket createSocket() throws IOException {
        return sslContext.getSocketFactory().createSocket();
    }
}
于 2013-10-26T02:43:34.600 回答