2

同僚が自己署名サーバーを使用するhttpsサーバーを実装するプロジェクトに取り組んでおり、httppostsを送信するAndroidアプリを設計しています。彼はcurlを使用してテストしましたが、問題はありません。必要に応じて、Android3.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;
}

それは多分あなたを助ける。ps。httpclient のバージョンは 4.3.1 です

于 2015-03-19T03:47:03.517 に答える