C
C
Chvalov2017-10-05 01:57:16
Java
Chvalov, 2017-10-05 01:57:16

OkHTTP how to ignore SSL certificate?

I am looking for a universal solution to bypass an SSL certificate using OkHTTP 3

My code:
private static final long CONNECT_TIMEOUT = 20000;   // 2 seconds
    private static final long READ_TIMEOUT = 20000;      // 2 seconds

    public static void GetHeader(){
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
                .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
                .followSslRedirects(false)
                .followRedirects(false)
                .build();

        Request request = new Request.Builder()
                .header("key", "test:test")
                .url("https://test-local.local")
                .build();
        try {
            Response response = client.newCall(request).execute();
            System.out.println("Редирект: " + response.isRedirect());
            System.out.println("Code: " + response.code());
            System.out.println("\nHeaders:\n" + response.headers());
            //System.out.println("\n\nBody:\n" + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


If the site has SSL I get an error javax.net.ssl.SSLPeerUnverifiedException
. This is fixed in this way:
.followRedirects(false)
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                })
                .build();


If the SSL certificate has expired / not valid or some other problems, then I get a number of new errors:
Errors (Spoiler)
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
...
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
...
Caused by: java.security.cert.CertPathValidatorException: timestamp check failed
...
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Thu Jan 12 18:13:11 EET 2017


How to force OkHTTP to ignore SSL certificates completely so that such errors do not occur?
And is it possible to prompt your root certificate (Certificate Authority)?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
mitaichik, 2017-10-05
@mitaichik

Xs will it help, did temporary solutions for working with self-signed certificates, cut out everything unnecessary, left only the essence:

@Component
public class ClientFactory
{
  @Value("${api.certificate.path}")
  private String certificatePath;

  @Value("${api.certificate.password}")
  private String certificatePassword;

  @Value("${api.params.site}")
  private String paramSite;

  /**
   *
   * @return
   * @throws Throwable
   */
  public OkHttpClient createClient() throws Throwable
  {
    return new OkHttpClient.Builder()
      .socketFactory(createSslContext().getSocketFactory())
      .build();
  }

  /**
   *
   * @return
   * @throws Throwable
   */
  private SSLContext createSslContext() throws Throwable
  {
    KeyStore ks = getCertificateKeyStore();

    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(ks, certificatePassword.toCharArray());

    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(kmf.getKeyManagers(), trustAll509(), new java.security.SecureRandom());

    return sslContext;

  }

  /**
   * @return
   */
  private TrustManager[] trustAll509()
  {
    return new TrustManager[] {
      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;}
      }
    };
  }
}

The most important thing here is to substitute your X509TrustManager in the SSLContext, which will stupidly skip everyone and not check anything.
But!!! This should be a temporary workaround for development/debug/tests. If you are using invalid certificates, you are doing something wrong.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question