webentwicklung-frage-antwort-db.com.de

javax.net.ssl.SSLHandshakeException: Java.security.cert.CertPathValidatorException: Vertrauensanker für Zertifizierungspfad nicht gefunden

Ich verwende Retrofit, um auf meine REST - API zuzugreifen. Wenn ich jedoch meine API hinter ssl stelle und mit http://myhost/myapi darauf zugreife, erhalte ich folgende Fehlermeldung:

Muss ich jetzt etwas mehr tun, da sich meine API hinter SSL befindet? 

So schließe ich mich an:

private final String API = "https://myhost/myapi";

private final RestAdapter REST_ADAPTER = new RestAdapter.Builder()
        .setServer(API)
        .setLogLevel(RestAdapter.LogLevel.FULL)
        .build();

01-10 09:49:55.621    2076-2100/com.myapp.mobile D/Retrofit﹕ javax.net.ssl.SSLHandshakeException: Java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
            at org.Apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.Java:401)
            at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.Java:209)
            at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.Java:478)
            at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.Java:433)
            at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.Java:290)
            at libcore.net.http.HttpEngine.sendRequest(HttpEngine.Java:240)
            at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.Java:282)
            at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.Java:497)
            at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.Java:134)
            at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.Java:90)
            at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.Java:48)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.Java:287)
            at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.Java:222)
            at $Proxy12.signin(Native Method)
            at com.myapp.loginactivity$3.doInBackground(LoginActivity.Java:143)
            at com.myapp.loginactivity$3.doInBackground(LoginActivity.Java:136)
            at Android.os.AsyncTask$2.call(AsyncTask.Java:287)
            at Java.util.concurrent.FutureTask.run(FutureTask.Java:234)
            at Android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.Java:230)
            at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1080)
            at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:573)
            at Java.lang.Thread.run(Thread.Java:841)
     Caused by: Java.security.cert.CertificateException: Java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
            at org.Apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.Java:282)
            at org.Apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.Java:202)
            at org.Apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.Java:595)
            at org.Apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
            at org.Apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.Java:398)
            at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.Java:209)
            at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.Java:478)
            at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.Java:433)
            at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.Java:290)
            at libcore.net.http.HttpEngine.sendRequest(HttpEngine.Java:240)
            at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.Java:282)
            at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.Java:497)
            at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.Java:134)
            at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.Java:90)
            at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.Java:48)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.Java:287)
            at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.Java:222)
            at $Proxy12.signin(Native Method)
            at com.myapp.LoginActivity$3.doInBackground(LoginActivity.Java:143)
            at com.myapp.LoginActivity$3.doInBackground(LoginActivity.Java:136)
            at Android.os.AsyncTask$2.call(AsyncTask.Java:287)
            at Java.util.concurrent.FutureTask.run(FutureTask.Java:234)
            at Android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.Java:230)
            at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1080)
            at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:573)
            at Java.lang.Thread.run(Thread.Java:841)
17
birdy

Der Grund dafür ist, dass die JVM/Dalvik den CA-Zertifikaten im System oder den Benutzerzertifikatspeichern nicht vertrauen.

Um dies mit Retrofit zu beheben: Wenn Sie okhttp verwenden, ist es bei einem anderen Client sehr ähnlich.
Sie müssen tun:

EIN). Erstellen Sie einen Zertifizierungsspeicher, der den öffentlichen Schlüssel der Zertifizierungsstelle enthält. Dazu müssen Sie das nächste Skript für * nix starten. Sie benötigen die OpenSL-Installation auf Ihrem Rechner und können von https://www.bouncycastle.org/ the jar bcprov-jdk16-1.46.jar herunterladen. Laden Sie diese Version nicht .__ herunter. Andernfalls ist die Version 1.5x nicht mit Android 4.0.4 kompatibel.

#!/bin/bash

if [ -z $1 ]; then
  echo "Usage: cert2Android<CA cert PEM file>"
  exit 1
fi

CACERT=$1
BCJAR=bcprov-jdk16-1.46.jar

TRUSTSTORE=mytruststore.bks
ALIAS=`openssl x509 -inform PEM -subject_hash -noout -in $CACERT`

if [ -f $TRUSTSTORE ]; then
    rm $TRUSTSTORE || exit 1
fi

echo "Adding certificate to $TRUSTSTORE..."
keytool -import -v -trustcacerts -alias $ALIAS \
      -file $CACERT \
      -keystore $TRUSTSTORE -storetype BKS \
      -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider \
      -providerpath $BCJAR \
      -storepass secret

echo "" 
echo "Added '$CACERT' with alias '$ALIAS' to $TRUSTSTORE..."

B). Kopieren Sie die Datei truststore mytruststore.bks in res/raw Ihres Projekts truststore location

C). Festlegen von SSLContext der Verbindung:

.............
okHttpClient = new OkHttpClient();
try {
    KeyStore ksTrust = KeyStore.getInstance("BKS");
    InputStream instream = context.getResources().openRawResource(R.raw.mytruststore);
    ksTrust.load(instream, "secret".toCharArray());

    // TrustManager decides which certificate authorities to use.
    TrustManagerFactory tmf = TrustManagerFactory
        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ksTrust);
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), null);

    okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException e) {
    e.printStackTrace();
}
.................
12
Fernando.

Hallo dasselbe Problem, das ich gelöst habe, du kannst es versuchen 

Java.security.cert.CertPathValidatorException: Vertrauensanker für Zertifizierungspfad nicht gefunden.NETWORK

 // SET SSL
public static OkClient setSSLFactoryForClient(OkHttpClient client) {
    try {
        // Create a trust manager that does not validate certificate chains
        final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(Java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(Java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    }

                    @Override
                    public Java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                }
        };

        // Install the all-trusting trust manager
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new Java.security.SecureRandom());
        // Create an ssl socket factory with our all-trusting manager
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();


        client.setSslSocketFactory(sslSocketFactory);
        client.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return new OkClient(client);
}
2
sushant gosavi

Es gibt vier Möglichkeiten, die ich kenne:

  • importieren Sie das Zertifikat in Ihre App und verwenden Sie es für die Verbindung
  • zertifikatsüberprüfung deaktivieren
  • fügen Sie Ihr Zertifikat den vertrauenswürdigen Systemzertifikaten in Android hinzu
  • kaufen Sie ein verifiziertes Zertifikat, das von Android akzeptiert wird

Ich gehe davon aus, dass Sie nicht dafür bezahlen wollen. Daher denke ich, dass die eleganteste Lösung die erste ist.

http://blog.crazybob.org/2010/02/Android-trusting-ssl-certificates.html

2
kupsef

Das SSL ist nicht richtig konfiguriert. Diese trustAnchor-Fehler bedeuten normalerweise, dass der Trust Store nicht gefunden werden kann. Überprüfen Sie Ihre Konfiguration und vergewissern Sie sich, dass Sie tatsächlich auf den Trust Store zeigen und dass dieser vorhanden ist.

Stellen Sie sicher, dass Sie eine -Djavax.net.ssl.trustStore-Systemeigenschaft festgelegt haben, und überprüfen Sie, ob der Pfad tatsächlich zum Trust Store führt.

Sie können SSL-Debugging auch aktivieren, indem Sie diese Systemeigenschaft -Djavax.net.debug=all festlegen. In der Debug-Ausgabe wird festgestellt, dass der Trust Store nicht gefunden werden kann.

1
Kevin Bowersox

Dies kann aus verschiedenen Gründen geschehen, darunter:

  1. Die Zertifizierungsstelle, die das Serverzertifikat ausgestellt hat, war unbekannt
  2. Das Serverzertifikat wurde nicht von einer Zertifizierungsstelle signiert, war jedoch selbst signiert
  3. Bei der Serverkonfiguration fehlt eine Zwischenzertifizierungsstelle

bitte überprüfen Sie diesen Link zur Lösung: https://developer.Android.com/training/articles/security-ssl.html#CommonProblems

0
Defuera

Ich benutze diese Klasse und habe kein Problem.

public class WCFs
{
    //  https://192.168.30.8/myservice.svc?wsdl
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "192.168.30.8";
private static final String SERVICE = "/myservice.svc?wsdl";
private static String SOAP_ACTION = "http://tempuri.org/iWCFserviceMe/";


public static Thread myMethod(Runnable rp)
{
    String METHOD_NAME = "myMethod";

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

    request.addProperty("Message", "Https WCF Running...");
    return _call(rp,METHOD_NAME, request);
}

protected static HandlerThread _call(final RunProcess rp,final String METHOD_NAME, SoapObject soapReq)
{
    final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    int TimeOut = 5*1000;

    envelope.dotNet = true;
    envelope.bodyOut = soapReq;
    envelope.setOutputSoapObject(soapReq);

    final HttpsTransportSE httpTransport_net = new HttpsTransportSE(URL, 443, SERVICE, TimeOut);

    try
    {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() // use this section if crt file is handmake
        {
            @Override
            public boolean verify(String hostname, SSLSession session)
            {
                return true;
            }
        });

        KeyStore k = getFromRaw(R.raw.key, "PKCS12", "password");
        ((HttpsServiceConnectionSE) httpTransport_net.getServiceConnection()).setSSLSocketFactory(getSSLSocketFactory(k, "SSL"));


    }
    catch(Exception e){}

    HandlerThread thread = new HandlerThread("wcfTd"+ Generator.getRandomNumber())
    {
        @Override
        public void run()
        {
            Handler h = new Handler(Looper.getMainLooper());
            Object response = null;

            for(int i=0; i<4; i++)
            {
                response = send(envelope, httpTransport_net , METHOD_NAME, null);

                try
                {if(Thread.currentThread().isInterrupted()) return;}catch(Exception e){}

                if(response != null)
                    break;

                ThreadHelper.threadSleep(250);
            }

            if(response != null)
            {
                if(rp != null)
                {
                    rp.setArguments(response.toString());
                    h.post(rp);
                }
            }
            else
            {
                if(Thread.currentThread().isInterrupted())
                    return;

                if(rp != null)
                {
                    rp.setExceptionState(true);
                    h.post(rp);
                }
            }

            ThreadHelper.stopThread(this);
        }
    };

    thread.start();

    return thread;
}


private static Object send(SoapSerializationEnvelope envelope, HttpTransportSE androidHttpTransport, String METHOD_NAME, List<HeaderProperty> headerList)
{
    try
    {
        if(headerList != null)
            androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope, headerList);
        else
            androidHttpTransport.call(SOAP_ACTION + METHOD_NAME, envelope);

        Object res = envelope.getResponse();

        if(res instanceof SoapPrimitive)
            return (SoapPrimitive) envelope.getResponse();
        else if(res instanceof SoapObject)
            return ((SoapObject) envelope.getResponse());
    }
    catch(Exception e)
    {}

    return null;
}

public static KeyStore getFromRaw(@RawRes int id, String algorithm, String filePassword)
{
    try
    {
        InputStream inputStream = ResourceMaster.openRaw(id);
        KeyStore keystore = KeyStore.getInstance(algorithm);
        keystore.load(inputStream, filePassword.toCharArray());
        inputStream.close();

        return keystore;
    }
    catch(Exception e)
    {}

    return null;
}

public static SSLSocketFactory getSSLSocketFactory(KeyStore trustKey, String SSLAlgorithm)
{
    try
    {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustKey);

        SSLContext context = SSLContext.getInstance(SSLAlgorithm);//"SSL" "TLS"
        context.init(null, tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
    catch(Exception e){}

    return null;
}

}

0
Ali Bagheri