Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/210.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
webview.loadUrl()中出现Android错误-找不到证书路径的信任锚点_Android_Ssl - Fatal编程技术网

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

webview.loadUrl()中出现Android错误-找不到证书路径的信任锚点,android,ssl,Android,Ssl,我有一个webview用于加载url,但不起作用 看看我的代码: public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WebVie

我有一个
webview
用于加载url,但不起作用

看看我的代码:

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


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

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

请帮助我。

创建WebViewClient:

private class WvClient extends WebViewClient 
{
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) {
        handler.proceed(); 
        // Ignore SSL certificate errors
    }
}
并将初始化的WebViewClient(“WvClient”)设置为您的WebView(“wv”):

或在一行中:

 wv.setWebViewClient(new WebViewClient() {@Override public void onReceivedSslError(WebView v, SslErrorHandler handler, SslError er){ handler.proceed(); }});
@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    // for SSLErrorHandler
    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setMessage(R.string.notification_error_ssl_cert_invalid);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}
private class WvClient extends WebViewClient 
{
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) {
        handler.proceed(); 
        // Ignore SSL certificate errors
    }
}

我正在处理这个问题,坦率地说,允许MITM攻击是不允许的。这里有一个支持钉扎的更干净的解决方案。将证书保存到原始资源文件夹中。
注意:遗憾的是,当您调用getCertificate()时,SSLError会给我们一个SslCertificate。SSL证书有点没用。它的公共API不允许您验证公钥,只允许验证创建日期、过期日期、颁发日期、颁发人。但是,如果打开此类,将看到一个未公开的X509Certificate成员变量。IDK为什么做出这个设计决定。但是有一个用于获取捆绑包的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;
}

这是正确的解决方案,谷歌将通过实施以下代码批准您的应用程序:

 wv.setWebViewClient(new WebViewClient() {@Override public void onReceivedSslError(WebView v, SslErrorHandler handler, SslError er){ handler.proceed(); }});
@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    // for SSLErrorHandler
    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setMessage(R.string.notification_error_ssl_cert_invalid);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}
private class WvClient extends WebViewClient 
{
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) {
        handler.proceed(); 
        // Ignore SSL certificate errors
    }
}
如果你使用下面的代码,那么在调试时它会工作,但谷歌会拒绝你的应用:

 wv.setWebViewClient(new WebViewClient() {@Override public void onReceivedSslError(WebView v, SslErrorHandler handler, SslError er){ handler.proceed(); }});
@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    // for SSLErrorHandler
    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setMessage(R.string.notification_error_ssl_cert_invalid);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}
private class WvClient extends WebViewClient 
{
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) {
        handler.proceed(); 
        // Ignore SSL certificate errors
    }
}

与anon
webView.setWebViewClient(新WebViewClient(){@Override public void onReceivedSlerror(webView视图,SslErrorHandler,SslError错误){handler.Procedure();}})相同这只是忽略所有SSL错误。绝对不是一个好的解决方案。通过在ReceivedSlerror上使用覆盖方法,google将拒绝您的应用程序。所以,这肯定不是一个合适的解决方案。但为什么当我的浏览器说我正在使用的同一个站点有一个好的证书时会出现SSL错误呢???嗨,Ryan。。。我们只需要覆盖这些方法?@RickON extend WebViewClient,是的,覆盖OnReceivedSlerror方法。仅供参考,如果您使用证书固定,并且您要固定的证书发生更改,您的应用程序将中断。只需考虑……通过使用RelayDebug方法,谷歌将拒绝您的应用程序。因此,这绝对不是一个正确的解决方案。@Mehullanpara这一声明的依据是什么?我可以确认,如果发布应用程序,google play将不会接受投票最多的答案。我在提交应用程序时收到以下消息:我们审查了APPNAME,包名为app.package,并发现您的应用程序使用的软件包含用户的安全漏洞。SSL错误处理程序感谢您提供了有效/良好的解决方案。