2017-03-03 1 views
0

내 HTTPS 서비스는 Tomcat (JDK 빈의 keytool을 사용하여 생성 된 .keystore)에서 호스팅됩니다.Android SSL - CertPathValidatorException

서버 인증서에 자체 서명 됨 &은 신뢰할 수있는 루트 기관에 설치하여 신뢰할 수있는 것으로 설정했습니다.

브라우저에서 서비스에 액세스 할 수 있습니다. 하지만 안드로이드에서 같은 일을 할 수 없습니다.

누군가 도와주세요. 나는 OpenSSL을 함께 iscreated host.cert (자산 디렉토리에 위치)

enter image description here

J2EE

에 미숙입니다.

나는 안드로이드 개발자 사이트 내가 아는

 try { 
      // Load CAs from an InputStream 
// (could be from a resource or ByteArrayInputStream or ...) 
      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
// From https://www.washington.edu/itconnect/security/ca/load-der.crt 

      InputStream inn=getAssets().open("host.cert"); 

      Certificate ca; 
      try { 
       ca = cf.generateCertificate(inn); 
       Log.i("TEST","ca=" + ((X509Certificate) ca).getSubjectDN()); 
      } finally { 
       inn.close(); 
      } 

// Create a KeyStore containing our trusted CAs 
      String keyStoreType = KeyStore.getDefaultType(); 
      KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
      keyStore.load(null, null); 
      keyStore.setCertificateEntry("ca", ca); 

// Create a TrustManager that trusts the CAs in our KeyStore 
      String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
      tmf.init(keyStore); 

// Create an SSLContext that uses our TrustManager 
      SSLContext context = SSLContext.getInstance("TLS"); 
      context.init(null, tmf.getTrustManagers(), null); 

// Tell the URLConnection to use a SocketFactory from our SSLContext 
      URL url = new URL("https://192.168.56.1:8443/RestHTTPS/JavaCodeGeeks/AuthorService/authors/"); 
      HttpsURLConnection urlConnection = 
        (HttpsURLConnection)url.openConnection(); 
      urlConnection.setSSLSocketFactory(context.getSocketFactory()); 
      InputStream in = urlConnection.getInputStream(); 

      byte arr[]=new byte[in.available()]; 
      in.read(arr); 

      String str=new String(arr); 
      Log.i("TEST",str); 

     }catch (Exception e){ 
      Log.e("TEST",e.toString()); 
      e.printStackTrace(); 
     } 

에서 코드를 사용하고, 이것은 이미 내가 해결책을 찾을 수 없습니까 인 질문을 요청합니다.

답변

0

아직 문제가있는 누군가를 위해 해결책을 게시 할 것입니다.

주로 (이 이미 Android developer site에 명시되어있다)

  • 3 가지를주의 바이 패스 기본 신뢰 관리자로 사용자 정의 신뢰 관리자를 만듭니다.
  • 호스트 이름이 수락 가능한지 수동으로 확인하십시오.
  • 테스트 목적으로 "localhost"또는 "127.0.0.1"을 사용하지 말고 대신 PC의 IP 주소를 사용하십시오. 여기

는 전체 코드

try { 

      // Things to Note 1 : Bypass default Trust Managers 
      TrustManager[] byPassTrustManagers = new TrustManager[]{new X509TrustManager() { 
       public X509Certificate[] getAcceptedIssuers() { 
        return new X509Certificate[0]; 
       } 

       public void checkClientTrusted(X509Certificate[] chain, String authType) { 
       } 

       public void checkServerTrusted(X509Certificate[] chain, String authType) { 
       } 
      }}; 

      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      InputStream inn = getAssets().open("keystore.cer"); 
      Certificate ca; 
      try { 
       ca = cf.generateCertificate(inn); 
       Log.i("TEST", "ca=" + ((X509Certificate) ca).getSubjectDN()); 
      } finally { 
       inn.close(); 
      } 


      String keyStoreType = "BKS"; 
      KeyStore.getDefaultType(); 
      KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
      keyStore.load(null, null); 
      keyStore.setCertificateEntry("ca", ca); 

      String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
      tmf.init(keyStore); 

      SSLContext context = SSLContext.getInstance("TLS"); 
      context.init(null, byPassTrustManagers, null); 

      // Things to Note 2 : Don't use "localhost" ,instead use IP 
      URL url = new URL("https://192.168.56.1:8443/RestHTTPS/JavaCodeGeeks/AuthorService/authors"); 
      HttpsURLConnection urlConnection = 
        (HttpsURLConnection) url.openConnection(); 

      urlConnection.setSSLSocketFactory(context.getSocketFactory()); 

      // Things to Note 3 : Allow all host 
      urlConnection.setHostnameVerifier(new HostnameVerifier() { 
       @Override 
       public boolean verify(String hostname, SSLSession session) { 
        return true; 
       } 
      }); 

      Log.i("TEST", urlConnection.getResponseMessage() + ""); 

      InputStream in = urlConnection.getInputStream(); 

      InputStreamReader isw = new InputStreamReader(in); 

      int data = isw.read(); 
      String str = ""; 
      while (data != -1) { 
       char current = (char) data; 
       data = isw.read(); 
       str += current; 
      } 

      Log.i("TEST", "" + str); 

     } catch (Exception e) { 
      Log.e("TEST", e.toString()); 
      e.printStackTrace(); 
     } 
입니다