HttpGet with HTTPS : SSLPeerUnverifiedException

前端 未结 6 1630
旧时难觅i
旧时难觅i 2020-11-27 13:29

Using HttpClient, I receive the following error when attempting to communicate over HTTPS:

Exception in thread \"main\" javax.net.ssl.SSLPeerUnverifie

相关标签:
6条回答
  • 2020-11-27 13:48

    Note: Do not do this in production code, use http instead, or the actual self signed public key as suggested above.

    On HttpClient 4.xx:

    import static org.junit.Assert.assertEquals;
    
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.junit.Test;
    
    public class HttpClientTrustingAllCertsTest {
    
        @Test
        public void shouldAcceptUnsafeCerts() throws Exception {
            DefaultHttpClient httpclient = httpClientTrustingAllSSLCerts();
            HttpGet httpGet = new HttpGet("https://host_with_self_signed_cert");
            HttpResponse response = httpclient.execute( httpGet );
            assertEquals("HTTP/1.1 200 OK", response.getStatusLine().toString());
        }
    
        private DefaultHttpClient httpClientTrustingAllSSLCerts() throws NoSuchAlgorithmException, KeyManagementException {
            DefaultHttpClient httpclient = new DefaultHttpClient();
    
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, getTrustingManager(), new java.security.SecureRandom());
    
            SSLSocketFactory socketFactory = new SSLSocketFactory(sc);
            Scheme sch = new Scheme("https", 443, socketFactory);
            httpclient.getConnectionManager().getSchemeRegistry().register(sch);
            return httpclient;
        }
    
        private TrustManager[] getTrustingManager() {
            TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
    
                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    // Do nothing
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    // Do nothing
                }
    
            } };
            return trustAllCerts;
        }
    }
    
    0 讨论(0)
  • 2020-11-27 13:48

    Using HttpClient 3.x, you need to do this:

    Protocol easyHttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
    Protocol.registerProtocol("https", easyHttps);
    

    An implementation of EasySSLProtocolSocketFactory can be found here.

    0 讨论(0)
  • 2020-11-27 13:49

    This exception will come in case your server is based on JDK 7 and your client is on JDK 6 and using SSL certificates. In JDK 7 sslv2hello message handshaking is disabled by default while in JDK 6 sslv2hello message handshaking is enabled. For this reason when your client trying to connect server then a sslv2hello message will be sent towards server and due to sslv2hello message disable you will get this exception. To solve this either you have to move your client to JDK 7 or you have to use 6u91 version of JDK. But to get this version of JDK you have to get the

    0 讨论(0)
  • 2020-11-27 13:55

    This answer follows on to owlstead and Mat's responses. It applies to SE/EE installations, not ME/mobile/Android SSL.

    Since no one has yet mentioned it, I'll mention the "production way" to fix this: Follow the steps from the AuthSSLProtocolSocketFactory class in HttpClient to update your trust store & key stores.

    1. Import a trusted certificate and generate a truststore file

    keytool -import -alias "my server cert" -file server.crt -keystore my.truststore

    1. Generate a new key (use the same password as the truststore)

    keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore

    1. Issue a certificate signing request (CSR)

    keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore

    1. (self-sign or get your cert signed)

    2. Import the trusted CA root certificate

    keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore

    1. Import the PKCS#7 file containg the complete certificate chain

    keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore

    1. Verify the resultant keystore file's contents

    keytool -list -v -keystore my.keystore

    If you don't have a server certificate, generate one in JKS format, then export it as a CRT file. Source: keytool documentation

    keytool -genkey -alias server-alias -keyalg RSA -keypass changeit
        -storepass changeit -keystore my.keystore
    
    keytool -export -alias server-alias -storepass changeit
        -file server.crt -keystore my.keystore
    
    0 讨论(0)
  • 2020-11-27 13:58

    Method returning a "secureClient" (in a Java 7 environnement - NetBeans IDE and GlassFish Server: port https by default 3920 ), hope this could help :

    public DefaultHttpClient secureClient() {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        SSLSocketFactory sf;
    
        KeyStore trustStore;
        FileInputStream trustStream = null;
        File truststoreFile;
        // java.security.cert.PKIXParameters for the trustStore
        PKIXParameters pkixParamsTrust;
    
        KeyStore keyStore;
        FileInputStream keyStream = null;
        File keystoreFile;
        // java.security.cert.PKIXParameters for the keyStore
        PKIXParameters pkixParamsKey;
    
        try {
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            truststoreFile = new File(TRUSTSTORE_FILE);
            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystoreFile = new File(KEYSTORE_FILE);
            try {
                trustStream = new FileInputStream(truststoreFile);
                keyStream = new FileInputStream(keystoreFile);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                trustStore.load(trustStream, PASSWORD.toCharArray());
                keyStore.load(keyStream, PASSWORD.toCharArray());
            } catch (IOException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            } catch (CertificateException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                pkixParamsTrust = new PKIXParameters(trustStore);
                // accepts Server certificate generated with keytool and (auto) signed by SUN
                pkixParamsTrust.setPolicyQualifiersRejected(false);
            } catch (InvalidAlgorithmParameterException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                pkixParamsKey = new PKIXParameters(keyStore);
                // accepts Client certificate generated with keytool and (auto) signed by SUN
                pkixParamsKey.setPolicyQualifiersRejected(false);
            } catch (InvalidAlgorithmParameterException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                sf = new SSLSocketFactory(trustStore);
                ClientConnectionManager manager = httpclient.getConnectionManager();
                manager.getSchemeRegistry().register(new Scheme("https", 3920, sf));
            } catch (KeyManagementException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            } catch (UnrecoverableKeyException ex) {
                Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
            }
    
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (KeyStoreException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        // use the httpclient for any httpRequest
        return httpclient;
    }
    
    0 讨论(0)
  • 2020-11-27 14:07

    Your local JVM or remote server may not have the required ciphers. go here

    https://www.oracle.com/java/technologies/javase-jce8-downloads.html

    and download the zip file that contains: US_export_policy.jar and local_policy.jar

    replace the existing files (you need to find the existing path in your JVM).

    on a Mac, my path was here. /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/security

    this worked for me.

    0 讨论(0)
提交回复
热议问题