webview.loadUrl()中的Android错误 - 找不到证书路径的信任锚

use*_*394 23 ssl android

我有一个webview加载网址,但没有工作.

看看我的代码:

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");


  }
}
Run Code Online (Sandbox Code Playgroud)

执行此代码时,android返回此错误:

Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Run Code Online (Sandbox Code Playgroud)

请帮帮我.

Luc*_*ler 50

创建WebViewClient:

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

并将初始化的WebViewClient("WvClient")设置为WebView(在这种情况下为"wv"):

wv.setWebViewClient(new WvClient());
Run Code Online (Sandbox Code Playgroud)

或者在一行中:

 wv.setWebViewClient(new WebViewClient() {@Override public void onReceivedSslError(WebView v, SslErrorHandler handler, SslError er){ handler.proceed(); }});
Run Code Online (Sandbox Code Playgroud)

  • 这只是忽略了所有SSL错误.绝对不是一个好的解决方案. (18认同)
  • 但是当我的浏览器说我正在使用的同一个网站有一个好的证书时,*为什么*它会收到 SSL 错误??? (5认同)
  • 将与匿名```相同。``webView.setWebViewClient(new WebViewClient(){ ``` (2认同)

Rya*_*som 9

我正在处理这个问题,坦率地说,允许MITM攻击是禁止的.这是一个支持固定的更清洁的解决方案.将证书保存到原始资源文件夹中.
注意:遗憾的是,当您调用getCertificate()时,SSLError会向我们提供SslCertificate.SslCertificate有点无用.它的公共API不允许您验证公钥,只允许发布的,过期日期,发布日期.但是,如果打开此类,您将看到未公开的X509Certificate成员变量.IDK为何做出这一设计决定.但是有一个用于获取Bundle的API,并且X509证书成员变量存储在那里.所以我们以这种方式访问​​它,因为证书上有更多有用的方法.

@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;
}
Run Code Online (Sandbox Code Playgroud)