2

我正在一个项目中,我的同事实现了一个 https 服务器,它使用一个自签名服务器,我正在设计一个向它发送 httpposts 的 android 应用程序。他使用 curl 对其进行了测试,没有任何问题。如果相关,我正在使用 Android 3.2。

按照此处的本教程,我生成了一个密钥库并将其添加到应用程序中,同时还创建了一个自定义 httpClient。我使用以下代码将 get 请求替换为 post:

    private InputStream postHttpConnection(String urlValue,
        JSONObject jsonPost, Context context) {
            InputStream inStream = null;
            URL url;
            try {
                url = new URL(urlValue);
                URLConnection conn = url.openConnection();
                if (!(conn instanceof HttpURLConnection))
                    Log.e("postHttpConnection", "Fail: " + "Not an HTTP connection");
            } catch (MalformedURLException e) {
                Log.e("postHttpConnection", "Fail: " + e);
            } catch (IOException e) {
                Log.e("postHttpConnection", "Fail: " + e);
            }
            try {
                DefaultHttpClient client = new MyHttpClient(context);
                HttpConnectionParams
                        .setConnectionTimeout(client.getParams(), 10000);
                HttpResponse postResponse;
                HttpPost post = new HttpPost(urlValue);
                StringEntity se = new StringEntity(jsonPost.toString());
                post.setEntity(se);
                post.setHeader("Accept", "application/json");
                post.setHeader("Content-type", "application/json");
                postResponse = client.execute(post);
                inStream = postResponse.getEntity().getContent();
            } catch (ClientProtocolException e) {
                Log.e("postHttpConnection", "Fail: " + e);
            } catch (IOException e) {
                Log.e("postHttpConnection", "Fail: " + e);
            }
            return inStream;
        }

当我通过适当的 JSONObject 使用此函数时,我收到以下错误:

    E/postHttpConnection(9236): Fail: javax.net.ssl.SSLException: Certificate for <address> doesn't contain CN or DNS subjectAlt

你能告诉我这与什么有关吗?谢谢你。

4

2 回答 2

4

问题不在于您的代码,而在于证书。您需要在证书的 SubjectName.CommonName 字段或证书的主题备用名称扩展中指定您的域名(客户端连接的域名)。您需要重新创建证书,并在执行此操作时查看有关如何指定 CommonName 的手册(您需要将其设置为“www.mydomain.com”之类的内容)。

于 2012-05-18T15:03:21.873 回答
0
private HttpClient getHttpClient(){
    RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory> create();
    ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
    registryBuilder.register("http", plainSF);
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        TrustStrategy anyTrustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                return true;
            }
        };
        SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, anyTrustStrategy)
                .build();
        LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        registryBuilder.register("https", sslSF);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    Registry<ConnectionSocketFactory> registry = registryBuilder.build();
    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
    HttpClient httpclient = HttpClientBuilder.create().setConnectionManager(connManager).build();

    return httpclient;
}

也许对你有帮助。附言。httpclient 版本为 4.3.1

于 2015-03-19T03:47:03.517 回答