2015-11-20 34 views
17

Tôi có webview để tải url, nhưng không hoạt động.Lỗi Android trong webview.loadUrl() - Dấu tin cậy cho đường dẫn chứng nhận không được tìm thấy

Nhìn vào mã của tôi:

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    WebView wv = (WebView) findViewById(R.id.webView); 

    //Log.d("rudyy", "aqui"); 
    wv.loadUrl("https://tripulanteaims.tam.com.br/wtouch/wtouch.exe/index"); 
    //Log.d("rudyy", "fim"); 


    } 
} 

Khi thực thi mã này, Android trả về lỗi này:

Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 

Help-tôi xin vui lòng.

Trả lời

37

Tạo một WebViewClient:

private class WvClient extends WebViewClient 
{ 
    @Override 
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) { 
     handler.proceed(); 
     // Ignore SSL certificate errors 
    } 
} 

Và thiết lập các WebViewClient khởi tạo ("WvClient") để WebView của bạn ("wv" trong trường hợp đó):

wv.setWebViewClient(new WvClient()); 

Hoặc trong một dòng:

wv.setWebViewClient(new WebViewClient() {@Override public void onReceivedSslError(WebView v, SslErrorHandler handler, SslError er){ handler.proceed(); }}); 
+1

xin vui lòng chấp nhận ... –

+1

sẽ giống với anon '' 'webView.setWebViewClient (WebViewClient mới() {@Override public void onReceivedSslError (xem WebView, SslErrorHandler handler, SslError lỗi) { handler.proceed(); } }); '' ' – tyoc213

+1

chính xác những gì tôi cần .. – MKY

4

Tôi đã đối phó với điều này và thẳng thắn cho phép các cuộc tấn công MITM là một o-không. Đây là một giải pháp sạch hơn hỗ trợ ghim. Lưu chứng chỉ vào thư mục tài nguyên thô của bạn.
LƯU Ý: Đáng buồn thay, SSLError cho chúng ta một SslCertificate khi bạn gọi getCertificate(). SslCertificate là loại vô dụng. Đó là API công khai không cho phép bạn xác minh khóa công khai, chỉ được tạo vào ngày hết hạn, được cấp cho, do. Tuy nhiên, nếu bạn mở lớp này, bạn sẽ thấy một biến thành viên X509Certificate không bị lộ ra. IDK lý do tại sao quyết định thiết kế này được thực hiện. Nhưng có một API để lấy Gói, và biến thành viên Chứng chỉ X509 được lưu trữ trong đó. Vì vậy, chúng tôi truy cập theo cách đó, bởi vì Chứng chỉ có nhiều phương pháp hữu ích hơn trên đó.

@Override 
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { 
    SslCertificate sslCertificateServer = error.getCertificate(); 
    Certificate pinnedCert = getCertificateForRawResource(R.raw.your_cert, mContext); 
    Certificate serverCert = convertSSLCertificateToCertificate(sslCertificateServer); 

    if(pinnedCert.equals(serverCert)) { 
     handler.proceed(); 
    } else { 
     super.onReceivedSslError(view, handler, error); 
    } 
} 

public static Certificate getCertificateForRawResource(int resourceId, Context context) { 
    CertificateFactory cf = null; 
    Certificate ca = null; 
    Resources resources = context.getResources(); 
    InputStream caInput = resources.openRawResource(resourceId); 

    try { 
     cf = CertificateFactory.getInstance("X.509"); 
     ca = cf.generateCertificate(caInput); 
    } catch (CertificateException e) { 
     Log.e(TAG, "exception", e); 
    } finally { 
     try { 
      caInput.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "exception", e); 
     } 
    } 

    return ca; 
} 

public static Certificate convertSSLCertificateToCertificate(SslCertificate sslCertificate) { 
    CertificateFactory cf = null; 
    Certificate certificate = null; 
    Bundle bundle = sslCertificate.saveState(sslCertificate); 
    byte[] bytes = bundle.getByteArray("x509-certificate"); 

    if (bytes != null) { 
     try { 
      CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 
      Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes)); 
      certificate = cert; 
     } catch (CertificateException e) { 
      Log.e(TAG, "exception", e); 
     } 
    } 

    return certificate; 
} 
+0

Hi Ryan ... chúng ta chỉ cần ghi đè lên những phương pháp này? – RickON

+0

@RickON mở rộng WebViewClient và có, ghi đè lên phương thức onReceivedSslError. –

+0

FYI, Nếu bạn sử dụng khóa chứng chỉ và chứng chỉ mà bạn đang ghim để được thay đổi, ứng dụng của bạn sẽ bị hỏng. Chỉ cần một cái gì đó để xem xét ... –

Các vấn đề liên quan