2017-05-05 102 views
15

我加HTTPPinning到OKHTTPClient的示例代碼:CertPathValidatorException:信任錨認證路徑沒有找到

OkHttpClient client = new OkHttpClient(); 
client.setSslSocketFactory(getPinnedCertSslSocketFactory(context)); 


private SSLSocketFactory getPinnedCertSslSocketFactory(Context context) { 
    try { 
     KeyStore trusted = KeyStore.getInstance("BKS"); 
     InputStream incontext.getResources().openRawResource(R.raw.prod_keystore); 
     trusted.load(in, "[email protected]".toCharArray()); 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
       TrustManagerFactory.getDefaultAlgorithm()); 
     trustManagerFactory.init(trusted); 
     sslContext.init(null, trustManagerFactory.getTrustManagers(), null); 
     return sslContext.getSocketFactory(); 
    } catch (Exception e) { 
     Log.e("MyApp", e.getMessage(), e); 
    } 
    return null; 
} 

我上傳的應用程序到Play商店中,並從過去的1年病房是運作良好。但是從最後1周開始它給下面的問題,我使用的版本com.squareup.okhttp的OkHttp:okhttp:使用OKHTTP3 2.7.4

java.security.cert.CertPathValidatorException: Trust anchor for 
      certification path not found. 
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 
        at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357) 
        at com.squareup.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:192) 
        at com.squareup.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149) 
        at com.squareup.okhttp.internal.io.RealConnection.connect(RealConnection.java:112) 
        at com.squareup.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184) 
        at com.squareup.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126) 
        at com.squareup.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95) 
        at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281) 
        at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224) 
        at com.squareup.okhttp.Call.getResponse(Call.java:286) 
        at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:243) 
        at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:205) 
        at com.squareup.okhttp.Call.execute(Call.java:80) 
        at com.venkat.good.http.MyHTTPThread.run(MyHTTPThread.java:492) 
        at com.venkat.good.http.MyHTTPThread.run(MyHTTPThread.java:76) 
        at java.lang.Thread.run(Thread.java:818) 

我解決了這個問題。

String hostname = "yourdomain.com"; 
    CertificatePinner certificatePinner = new CertificatePinner.Builder() 
.add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") 
.build(); 
    OkHttpClient client = OkHttpClient.Builder() 
.certificatePinner(certificatePinner) 
.build(); 

    Request request = new Request.Builder() 
.url("https://" + hostname) 
.build(); 
client.newCall(request).execute(); 

但我想知道爲什麼以前OkHttp2版本的作品了一些日子之後,它提出了一個問題?

+0

是否有機會在服務器端更改內容或證書已過期? –

+0

我在創建BKS文件時沒有指定任何日期,服務器人員在他們身邊沒有任何改變。 – Venkat

回答

0

嘗試使用自定義信任的概念將您的應用程序限制到您的證書。

/* 
* Copyright (C) 2015 Square, Inc. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 
package okhttp3.recipes; 

import java.io.IOException; 
import java.io.InputStream; 
import java.security.GeneralSecurityException; 
import java.security.KeyStore; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateFactory; 
import java.util.Arrays; 
import java.util.Collection; 
import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocketFactory; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.TrustManagerFactory; 
import javax.net.ssl.X509TrustManager; 
import okhttp3.CertificatePinner; 
import okhttp3.Headers; 
import okhttp3.OkHttpClient; 
import okhttp3.Request; 
import okhttp3.Response; 
import okio.Buffer; 

public final class CustomTrust { 
    private final OkHttpClient client; 

    public CustomTrust() { 
    X509TrustManager trustManager; 
    SSLSocketFactory sslSocketFactory; 
    try { 
     trustManager = trustManagerForCertificates(trustedCertificatesInputStream()); 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(null, new TrustManager[] { trustManager }, null); 
     sslSocketFactory = sslContext.getSocketFactory(); 
    } catch (GeneralSecurityException e) { 
     throw new RuntimeException(e); 
    } 

    client = new OkHttpClient.Builder() 
     .sslSocketFactory(sslSocketFactory, trustManager) 
     .build(); 
    } 

    public void run() throws Exception { 
    Request request = new Request.Builder() 
     .url("https://publicobject.com/helloworld.txt") 
     .build(); 

    try (Response response = client.newCall(request).execute()) { 
     if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

     Headers responseHeaders = response.headers(); 
     for (int i = 0; i < responseHeaders.size(); i++) { 
     System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); 
     } 

     System.out.println(response.body().string()); 
    } 
    } 

    /** 
    * Returns an input stream containing one or more certificate PEM files. This implementation just 
    * embeds the PEM files in Java strings; most applications will instead read this from a resource 
    * file that gets bundled with the application. 
    */ 
    private InputStream trustedCertificatesInputStream() { 
    // PEM files for root certificates of Comodo and Entrust. These two CAs are sufficient to view 
    // https://publicobject.com (Comodo) and https://squareup.com (Entrust). But they aren't 
    // sufficient to connect to most HTTPS sites including https://godaddy.com and https://visa.com. 
    // Typically developers will need to get a PEM file from their organization's TLS administrator. 
    String comodoRsaCertificationAuthority = "" 
     + "-----BEGIN CERTIFICATE-----\n" 
     + "MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB\n" 
     + "hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" 
     + "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\n" 
     + "BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5\n" 
     + "MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\n" 
     + "EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\n" 
     + "Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh\n" 
     + "dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR\n" 
     + "6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X\n" 
     + "pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC\n" 
     + "9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV\n" 
     + "/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf\n" 
     + "Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z\n" 
     + "+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w\n" 
     + "qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah\n" 
     + "SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC\n" 
     + "u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf\n" 
     + "Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq\n" 
     + "crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E\n" 
     + "FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB\n" 
     + "/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl\n" 
     + "wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM\n" 
     + "4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV\n" 
     + "2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna\n" 
     + "FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ\n" 
     + "CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK\n" 
     + "boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke\n" 
     + "jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL\n" 
     + "S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb\n" 
     + "QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl\n" 
     + "0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB\n" 
     + "NVOFBkpdn627G190\n" 
     + "-----END CERTIFICATE-----\n"; 
    String entrustRootCertificateAuthority = "" 
     + "-----BEGIN CERTIFICATE-----\n" 
     + "MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC\n" 
     + "VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0\n" 
     + "Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW\n" 
     + "KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl\n" 
     + "cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw\n" 
     + "NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw\n" 
     + "NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy\n" 
     + "ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV\n" 
     + "BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ\n" 
     + "KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo\n" 
     + "Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4\n" 
     + "4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9\n" 
     + "KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI\n" 
     + "rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi\n" 
     + "94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB\n" 
     + "sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi\n" 
     + "gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo\n" 
     + "kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE\n" 
     + "vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA\n" 
     + "A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t\n" 
     + "O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua\n" 
     + "AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP\n" 
     + "9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/\n" 
     + "eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m\n" 
     + "0vdXcDazv/wor3ElhVsT/h5/WrQ8\n" 
     + "-----END CERTIFICATE-----\n"; 
    return new Buffer() 
     .writeUtf8(comodoRsaCertificationAuthority) 
     .writeUtf8(entrustRootCertificateAuthority) 
     .inputStream(); 
    } 

    /** 
    * Returns a trust manager that trusts {@code certificates} and none other. HTTPS services whose 
    * certificates have not been signed by these certificates will fail with a {@code 
    * SSLHandshakeException}. 
    * 
    * <p>This can be used to replace the host platform's built-in trusted certificates with a custom 
    * set. This is useful in development where certificate authority-trusted certificates aren't 
    * available. Or in production, to avoid reliance on third-party certificate authorities. 
    * 
    * <p>See also {@link CertificatePinner}, which can limit trusted certificates while still using 
    * the host platform's built-in trust store. 
    * 
    * <h3>Warning: Customizing Trusted Certificates is Dangerous!</h3> 
    * 
    * <p>Relying on your own trusted certificates limits your server team's ability to update their 
    * TLS certificates. By installing a specific set of trusted certificates, you take on additional 
    * operational complexity and limit your ability to migrate between certificate authorities. Do 
    * not use custom trusted certificates in production without the blessing of your server's TLS 
    * administrator. 
    */ 
    private X509TrustManager trustManagerForCertificates(InputStream in) 
     throws GeneralSecurityException { 
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 
    Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in); 
    if (certificates.isEmpty()) { 
     throw new IllegalArgumentException("expected non-empty set of trusted certificates"); 
    } 

    // Put the certificates a key store. 
    char[] password = "password".toCharArray(); // Any password will work. 
    KeyStore keyStore = newEmptyKeyStore(password); 
    int index = 0; 
    for (Certificate certificate : certificates) { 
     String certificateAlias = Integer.toString(index++); 
     keyStore.setCertificateEntry(certificateAlias, certificate); 
    } 

    // Use it to build an X509 trust manager. 
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
     KeyManagerFactory.getDefaultAlgorithm()); 
    keyManagerFactory.init(keyStore, password); 
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
     TrustManagerFactory.getDefaultAlgorithm()); 
    trustManagerFactory.init(keyStore); 
    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); 
    if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { 
     throw new IllegalStateException("Unexpected default trust managers:" 
      + Arrays.toString(trustManagers)); 
    } 
    return (X509TrustManager) trustManagers[0]; 
    } 

    private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { 
    try { 
     KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     InputStream in = null; // By convention, 'null' creates an empty key store. 
     keyStore.load(in, password); 
     return keyStore; 
    } catch (IOException e) { 
     throw new AssertionError(e); 
    } 
    } 

    public static void main(String... args) throws Exception { 
    new CustomTrust().run(); 
    } 
} 
+0

我想知道爲什麼以前的OkHttp2版本工作了幾天,之後它引發了這個問題? – Venkat

+0

這是okhttp3雖然 – Remario

+0

okhttp3正在工作,但我需要解釋我的客戶端爲什麼okhttp2幾天後停止工作,沒有做任何改變的發展。 – Venkat

相關問題