5

Java 経由で HTTPS サイトと対話する際に問題があります。私のプログラムは、プログラムが実行されるたびに、信頼されていない証明書を持つ 1 つの URL を使用します。このプログラムは、複数のシステムで実行する必要があります。現在、私は以下を持っています:

public class A{
    HostnameVerifier hv = new HostnameVerifier(){
        public boolean verify(String urlHostName, SSLSession session){
            return true;
        }       
    };

    HttpsURLConnection.setDefaultHostnameVerifier(hv);

    javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
    javax.net.ssl.TrustManager tm = new miTM();
    trustAllCerts[0] = tm;
    javax.net.ssl.SSLContext sc = null;
    try {
        sc = javax.net.ssl.SSLContext.getInstance("SSL");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    try {
        sc.init(null, trustAllCerts, null);
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }
   javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager{

    public java.security.cert.X509Certificate[] getAcceptedIssuers(){
        return null;
    }

    public boolean isServerTrusted(java.security.cert.X509Certificate[] certs){
        return true;
        }

    public boolean isClientTrusted(java.security.cert.X509Certificate[] certs){
        return true;
    }

    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException{
        return;
    }

    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException{
        return;
        }
}

このコードを使用すると、次のことをうまく実行できます。

URL url = new URL(urlString);
URLConnection cnx = url.openConnection();
cnx.connect();

InputStream ins = cnx.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(ins));
String curline;
while( (curline = in.readLine()) != null ) {
     System.out.println(curline);
}

ただし、次のことはできません。

httpClient = new HttpClient();
PostMethod postMethod = null;
int intResult = 0;
postMethod = new PostMethod(authURL);
Enumeration emParams = authParams.propertyNames();
while (emParams.hasMoreElements()) {
  String paramName = (String) emParams.nextElement();
  String paramValue = authParams.getProperty(paramName);
     postMethod.addParameter(paramName, paramValue);
}

intResult = httpClient.executeMethod(postMethod);
postMethod.releaseConnection();
ins.close();

executeMethod(postMethod) を実行すると、SSLHandshakeException や CertPathBuilderException などが発生します。

これを解決するにはどうすればよいですか? 証明書を受け入れるか、すべての証明書の検証をバイパスすることを考えています (プログラムはプライベート ネットワーク内で内部的に実行されるため)。

ありがとう

4

2 に答える 2

5

Apache HttpClient 3 を使用しているようです。これが実際にバージョン 3 である場合は、 Apache HttpClient 3 SSL ガイドSecureProtocolSocketFactoryで説明されているように、独自のものを構築する必要があります。ここに例があります。

Apache HttpClient 4 の場合、この質問への回答(ホスト名の検証に関するメモを含む)で説明されているようにSSLContext、 (HttpClient) のコンストラクターにan を渡すことができるはずです。SSLSocketFactory

ただし、一般的に言えば、このアプローチには従わないでください。そうすることで、SSL/TLS 接続の認証部分を効果的に無効にすることになり、MITM 攻撃に対して脆弱になります。

この回答で説明されているように、代わりにクライアントの信頼ストアにサーバー証明書を明示的にインポートする必要があります。

証明書を受け入れるか、すべての証明書の検証をバイパスすることを考えています (プログラムはプライベート ネットワーク内で内部的に実行されるため)。

あなたが言っているのは、プライベート ネットワーク内でのみ暗号化に SSL/TLS を使用しても構わないと思っているということです。その理由は、そのユーザーが自分のマシンを迂回する可能性のあるトラフィックを調べないほど十分に信頼していないためです。これらのユーザーは MITM 攻撃を実行できないと想定しています。これはあまり意味がありません。それらを十分に信頼している場合は、データを平文で送信することもできます。そうでない場合は、認証手順 (証明書とホスト名の検証) を含め、SSL/TLS を適切に実装する必要があります。

于 2012-01-30T09:44:27.860 に答える
1

Http クライアント 4.3:

     HttpClientBuilder cb = HttpClientBuilder.create();
     SSLContextBuilder sslcb = new SSLContextBuilder();
     sslcb.loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()), new TrustSelfSignedStrategy());
     cb.setSslcontext(sslcb.build());
     CloseableHttpClient httpclient = cb.build();
于 2014-09-02T09:53:18.067 に答える