2017-03-03 4 views
0

私のHTTPSサービスはTomCat(JDKのbinのkeytoolの助けを借りて作成された.keystore)でホストされています。Android SSL - CertPathValidatorException

サーバー証明書には自己署名&があり、信頼されたルート機関にインストールすることで信頼できるものになりました。

ブラウザからサービスにアクセスできます。しかし、Androidから同じことをすることはできません。

誰か助けてください。私は、OpenSSLでiscreated host.cert(資産のディレクトリに配置された)

enter image description here

J2EE

に新参です。

私は私が知っているAndroidデベロッパーサイト

 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(); 
     } 

からコードスニペットを使用しています、これは既に私は解決策を見つけることができませんquestion.But頼まれます。

答えて

0

誰かがまだ問題に直面しているので、解決策を投稿します。

は、主に3つの事(これは既にAndroid developer siteに記載されている)

  • は、デフォルトのトラストマネージャをバイパスするカスタムトラストマネージャを作成します注意してください。
  • ホスト名が受け入れ可能であることを手動で確認します。
  • "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(); 
     } 
です
関連する問題