1

나는이 URL을 열기 위해 webview를 사용하는 하나의 클래스를 가지고 있습니다 : https://eaadhaar.uidai.gov.in 그리고이 아래 코드를 사용하여 로컬 인증서를 만들었습니다. 200 응답을 받았습니다. 하지만 내 질문은 어떻게 사용자에게 웹 페이지를 표시 진행합니다. 이 코드를 테스트 한 :https URL에 액세스하는 webview를 기반으로 Android 앱을 만들 수 있습니까

public class WebViewFragment extends Fragment { 

    public final String TAG = WebViewFragment.class.getSimpleName(); 
    private WebView webView; 

    public static final int DEFAULT_BUFFER_SIZE = 2048; 
    public static final String DEFAULT_CHARSET_NAME = "UTF-8"; 

    public WebViewFragment() { 

    } 

    public static WebViewFragment newInstance() { 
     return new WebViewFragment(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.layout_webview_fragment, container, false); 

     initGlobal(view); 
     return view; 
    } 

    private void initGlobal(View view) { 
     webView = (WebView) view.findViewById(R.id.webview); 
     //MyBrowser is a custom class which extends Webviewclient which loads the given url in the webview 
     webView.setWebViewClient(new MyBrowser()); 
     webView.getSettings().setJavaScriptEnabled(true); 
     webView.getSettings().setDomStorageEnabled(true); 

     webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); 

//  webView.loadUrl("http://www.google.com"); 
//  webView.loadUrl("https://www.github.com"); 
//  webView.loadUrl("https://eaadhaar.uidai.gov.in/"); 

     try { 
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 

      StrictMode.setThreadPolicy(policy); 

      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      InputStream caInput = new BufferedInputStream(getActivity().getResources().openRawResource(R.raw.newcertificate)); 
      Certificate ca; 
      try { 
       ca = cf.generateCertificate(caInput); 
       System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 
      } finally { 
       caInput.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 a SSLContext with the certificate 
      SSLContext sslContext = SSLContext.getInstance("TLS"); 
      sslContext.init(null, tmf.getTrustManagers(), null); 

      // Create a HTTPS connection 
      URL url = new URL("https://eaadhaar.uidai.gov.in"); 
      HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 
      conn.setSSLSocketFactory(sslContext.getSocketFactory()); 

      InputStream in = conn.getInputStream(); 
      int lastResponseCode = conn.getResponseCode(); 
      Log.e(TAG, "response code=" + lastResponseCode); 

      if (lastResponseCode == 200) { 
       Toast.makeText(getActivity(), "Response code==" + lastResponseCode, Toast.LENGTH_SHORT).show(); 
      } 
      copyInputStreamToOutputStream(in, System.out, 2048, true, true); 


     } catch (Exception e) { 
      Log.e(TAG, "Exception========" + e.toString()); 
     } 
    } 

    public void copyInputStreamToOutputStream(InputStream from, OutputStream to, int bufferSize, boolean closeInput, boolean closeOutput) { 
     try { 
      int totalBytesRead = 0; 
      int bytesRead = 0; 
      int offset = 0; 
      byte[] data = new byte[bufferSize]; 

      while ((bytesRead = from.read(data, offset, bufferSize)) > 0) { 
       totalBytesRead += bytesRead; 
       to.write(data, offset, bytesRead); 
       Log.e(TAG, "Copied " + totalBytesRead + " bytes"); 
      } 
      closeStreams(from, to, closeInput, closeOutput); 
     } catch (Exception e) { 
      closeStreams(from, to, closeInput, closeOutput); 
      e.printStackTrace(); 
      throw new RuntimeException(e); 
     } 
    } 


    public void closeStreams(InputStream from, OutputStream to, boolean closeInput, boolean closeOutput) { 
     try { 
      if (to != null) 
       to.flush(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     try { 
      if (closeInput && from != null) 
       from.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     try { 
      if (closeOutput && to != null) 
       to.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 
+0

정확한 질문은 무엇입니까? 그것은 "UI에서 웹보기를 표시하는 방법"또는 "can webview load HTTPS"또는 "can webview로드 할 수있는 HTTPS 페이지는 인증서가 운영 체제에서 신뢰할 수 없으며 사용자 지정 CA 저장소를 사용하여 인증서의 유효성을 검사하고 싶습니다"? –

+0

@ jakub.g 사실 실제로 위의 URL을 webview에 표시하고 빈 화면을 표시하려고합니다.이 문제를 해결하기 위해 onReceivedSslError 메서드를 사용해야하는 모든 방법이 있습니다. 나는 또한 URL에 액세스하기 위해 사용자 정의 키 저장소가 필요하다는 잘못된 생각을했습니다. –

+0

빈 화면이 표시되면 어떤 이유로 든 https 인증서를 확인할 수 없음을 의미합니다. 프로덕션 앱의'onReceivedSslError'에서 단지'handler.proceed()'를하지 말아야한다는 점에 유의하십시오. 왜냐하면 HTTPS의 목적을 저해하는 앱은 man-in-the-middle 공격을 받기 쉽기 때문입니다. –

답변

0

문제는 서버가 여기에 참조

을 (중개 인증서를 전송하지 않습니다) 전체 인증서 체인을 전송하지 않습니다 가능성이 높습니다 :

https://www.ssllabs.com/ssltest/analyze.html?d=eaadhaar.uidai.gov.in&latest

Certification Paths을 클릭하면 옆에 Extra download이 표시됩니다.

는 웹보기 특정 일 : 그것은 (중 하나를 수행하거나 사용자가 다른 페이지를 탐색하는 동안 그들이 본 적이 인증서 표시 캐시 크롬이나 파이어 폭스와 같은 일반 브라우저)

당신을 중간 인증서 표시를 가져 오지 않는다 모든 중간 인증서를 보내려면 서버 admin/ops에 문의해야합니다. 우리 애플 리케이션과 비슷한 문제가 있었고 SSL 핸드 셰이크에서 모든 중간 인증서를 보내서 해결되었습니다.

오버라이드 onReceivedSslError은 문제를 해결하기위한 안전하지 않은 방법이므로 프로덕션 응용 프로그램에서 사용해서는 안됩니다. 개발 전용 도구로 사용하십시오.