Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

html 页面中无法展示 https 的图片 #160

Open
yorkvolvo opened this issue Jul 5, 2019 · 2 comments
Open

html 页面中无法展示 https 的图片 #160

yorkvolvo opened this issue Jul 5, 2019 · 2 comments

Comments

@yorkvolvo
Copy link

问题描述

我在页面中设置 img src 属性的时候,如果图片设置成我们服务器的 https 链接,那么图片就不会显示。代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
	<title>Title Here</title>
	<script type="text/javascript"></script>
</head>
<body>

<div class="uwh-bg umar-r-ect uwh-bg-img" id="imgtest">
	<img class="upimg" id="imgtesta" src="https://172.28.1.209/image......" width="100px" height="100px"/>
</div>

</body>
</html>

不能正确显示来自服务器的图片:

image

我排查后发现这是 https 证书配置问题,错误日志:

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

页面中的 https 请求都是没问题的:

appcan.ajax({
            type:"POST",
            url:baseUrl+url,
            data:data
            offline:false,
            expire:1000,
            timeout : 30000,
            dataType: 'json',
            beforeSend:function(xhr){
            },
            success:function(ret,status,xhr){           
            },
           error:function(xhr,type){  
        }
     });

尝试的解决办法

我试着在修改引擎代码,不要去做证书校验,在 org.zywx.wbpalmstar.platform.certificates.Http 中忽略证书校验:

public class Http {

    public static HashMap<String, KeyStore> KEY_STORE = new HashMap<String, KeyStore>();
    public static String algorithm = "X509";
    public static String keyType = "pkcs12";
    /**
     * 是否检查https证书为可信机构颁发
     */
    private static boolean isCheckTrustCert = false;

    private static InputStream getInputStream(String cPath, Context ctx)
            throws IOException, FileNotFoundException {
        InputStream inStream;
        String assertFile = "file:///android_asset/";
        String sdcardFile = "/sdcard/";
        String wgtFile = "widget/";
        String file = "file://";
        if (cPath.contains(assertFile)) {
            cPath = cPath.substring(assertFile.length());
            AssetManager asset = ctx.getAssets();
            inStream = asset.open(cPath);
        } else if (cPath.contains(sdcardFile)) {
            if (cPath.contains(file)) {
                cPath = cPath.substring("file://".length());
            }
            inStream = new FileInputStream(cPath);
        } else if (cPath.startsWith(wgtFile)) {
            AssetManager asset = ctx.getAssets();
            inStream = asset.open(cPath);
        } else {
            inStream = new FileInputStream(cPath);
        }
        return inStream;
    }

    public static javax.net.ssl.SSLSocketFactory getSSLSocketFactoryWithCert(String cPassWord, String cPath, Context ctx) {
        Log.e("httptest", "httptest == getSSLSocketFactoryWithCert(String cPassWord, String cPath, Context ctx)");

        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("SSL");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        TrustManager[] tm = {new HX509TrustManager()};
        try {
            sslContext.init(null, tm, new java.security.SecureRandom());
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext.getSocketFactory();
    }

    public static javax.net.ssl.SSLSocketFactory getSSLSocketFactory() {
        Log.e("httptest", "httptest == getSSLSocketFactory()");
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("SSL");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        TrustManager[] tm = {new HX509TrustManager()};
        try {
            sslContext.init(null, tm, new java.security.SecureRandom());
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext.getSocketFactory();
    }

    public static HttpsURLConnection getHttpsURLConnection(URL url) throws Exception {
        Log.e("httptest", "httptest == getHttpsURLConnection(URL url)");
        HttpsURLConnection mConnection = null;
        mConnection = (HttpsURLConnection) url.openConnection();
        javax.net.ssl.SSLSocketFactory ssFact = null;
        ssFact = Http.getSSLSocketFactory();
        ((HttpsURLConnection) mConnection).setSSLSocketFactory(ssFact);
        if (!isCheckTrustCert()) {
            ((HttpsURLConnection) mConnection)
                    .setHostnameVerifier(new HX509HostnameVerifier());
        } else {
            ((HttpsURLConnection) mConnection)
                    .setHostnameVerifier(new HX509HostnameVerifier());
        }
        return mConnection;
    }

    public static HttpsURLConnection getHttpsURLConnection(String urlString) throws Exception {
        URL url=new URL(urlString);
        HttpsURLConnection mConnection = getHttpsURLConnection(url);
        return mConnection;
    }

    public static HttpsURLConnection getHttpsURLConnectionWithCert(URL url,
            String cPassWord, String cPath, Context ctx) throws Exception {
        HttpsURLConnection mConnection = null;
        mConnection = (HttpsURLConnection) url.openConnection();
        javax.net.ssl.SSLSocketFactory ssFact = null;
        ssFact = Http.getSSLSocketFactoryWithCert(cPassWord, cPath, ctx);
        ((HttpsURLConnection) mConnection).setSSLSocketFactory(ssFact);
        if (!isCheckTrustCert()) {
            ((HttpsURLConnection) mConnection)
                    .setHostnameVerifier(new HX509HostnameVerifier());
        } else {
            ((HttpsURLConnection) mConnection)
                    .setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
        }
        return mConnection;
    }

    public static boolean isCheckTrustCert() {
        return isCheckTrustCert;
    }

    public static void setCheckTrustCert(boolean isCheckTrustCert) {
        Http.isCheckTrustCert = isCheckTrustCert;
    }
}

但是这并没有解决我们的问题,我在网上搜索之后发现 appcan 类似的问题:https自定义证书如何能通过安全认证,但是也是一直没有解决。

可能的解决方案

网上搜索发现在 onReceivedSslError 方法中接受证书就可以解决问题。

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
        handler.proceed();
    }
});

问题

  1. 我该如何在 appcan 项目中配置 https 证书呢?

  2. 或者我该如何让我的 appcan 项目里全局请求网络的时候忽略校验证书呢?

PS:项目已整体迁移到 Android Studio 中了。

@yorkvolvo
Copy link
Author

@sandy1108 , 能帮忙看下这个 issue 吗?

@sandy1108
Copy link
Collaborator

@sandy1108 , 能帮忙看下这个 issue 吗?

你的问题说的可真详细啊。你说的里面不是写了吗,onReceivedSslError这个方法改写一下就可以了。忽略证书校验后,对于一些安全检测的机构来说,这是不安全的。所以可能没有把这个代码合并到主干中。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants