javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found

前端 未结 11 705
清酒与你
清酒与你 2020-11-27 15:59

I am using Retrofit to access my REST API. However, when I put my API behind ssl and access it by http://myhost/myapi then I get this error:

Do I need t

相关标签:
11条回答
  • 2020-11-27 16:32

    This can happen for several reasons, including:

    1. The CA that issued the server certificate was unknown
    2. The server certificate wasn't signed by a CA, but was self signed
    3. The server configuration is missing an intermediate CA

    please check out this link for solution: https://developer.android.com/training/articles/security-ssl.html#CommonProblems

    0 讨论(0)
  • 2020-11-27 16:32

    The SSL is not properly configured. Those trustAnchor errors usually mean that the trust store cannot be found. Check your configuration and make sure you are actually pointing to the trust store and that it is in place.

    Make sure you have a -Djavax.net.ssl.trustStore system property set and then check that the path actually leads to the trust store.

    You can also enable SSL debugging by setting this system property -Djavax.net.debug=all. Within the debug output you will notice it states that it cannot find the trust store.

    0 讨论(0)
  • 2020-11-27 16:35

    There are 4 ways that I know of:

    • import the certificate to your app and use it for the connection
    • disable certificate checking
    • add your certificate to the trusted system certificates in Android
    • buy a verified certificate that is accepted by Android

    I assume you don't want to pay for this, so I think the most elegant solution is the first one, what can be accomplished this way:

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

    0 讨论(0)
  • 2020-11-27 16:35

    OK, So I faced the same issue for my android app which have secured domain i.e. HTTPS,

    These are the steps:

    1. You need SSL certificate file i.e. ".pem" file for your domain.
    2. put that file into the assets folder
    3. Just copy and paste this class in your project

    public class SSlUtilsw {

    public static SSLContext getSslContextForCertificateFile(Context context, String fileName){
    
        try {
            KeyStore keyStore = SSlUtilsw.getKeyStore(context, fileName);
            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null,trustManagerFactory.getTrustManagers(),new SecureRandom());
            return sslContext;
    
        }catch (Exception e){
            String msg = "Error during creating SslContext for certificate from assets";
            e.printStackTrace();
            throw new RuntimeException(msg);
        }
    }
    
    public static KeyStore getKeyStore(Context context,String fileName){
        KeyStore keyStore = null;
        try {
            AssetManager assetManager=context.getAssets();
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput=assetManager.open(fileName);
            Certificate ca;
            try {
                ca=cf.generateCertificate(caInput);
    
            }finally {
                caInput.close();
            }
            String keyStoreType=KeyStore.getDefaultType();
            keyStore=KeyStore.getInstance(keyStoreType);
            keyStore.load(null,null);
            keyStore.setCertificateEntry("ca",ca);
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyStore;
    }}
    
    1. In your http client class of retrofit, add this

          val trustManagerFactory: TrustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
      trustManagerFactory.init(null as KeyStore?)
      val trustManagers: Array<TrustManager> = trustManagerFactory.trustManagers
      if (trustManagers.size != 1 || trustManagers[0] !is X509TrustManager) {
          throw IllegalStateException("Unexpected default trust managers:" + trustManagers.contentToString())
      }
      val trustManager = trustManagers[0] as X509TrustManager
      
      httpClient.sslSocketFactory(SSlUtils.getSslContextForCertificateFile(
              applicationContextHere, "yourcertificate.pem").socketFactory, trustManager)
      

    And that's it.

    0 讨论(0)
  • 2020-11-27 16:41

    I use this class and have no 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 讨论(0)
  • 2020-11-27 16:43

    This is a Server-Side issue.

    Server side have .crt file for HTTPS, here we have to do combine

    cat your_domain.**crt** your_domain.**ca-bundle** >> ssl_your_domain_.crt 
    

    then restart.

    sudo service nginx restart
    

    For me working fine.

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