【问题标题】:Android volley self signed HTTPS trust anchor for certification path not found未找到用于认证路径的 Android volley 自签名 HTTPS 信任锚
【发布时间】:2015-11-16 05:06:34
【问题描述】:

我是安卓新手。 这个问题已经被问过很多次了,但我已经回答了这里几乎所有的问题。

我正在尝试在 Node.Js 服务器(使用 express)和 Android 上的 Volley 上使用自签名证书。
使用:http://blog.applegrew.com/2015/04/using-pinned-self-signed-ssl-certificate-with-android-volley/

我无法使用http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/,因为我的应用程序中有太多代码需要更改。

这就是错误。

javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。

我的 volleysingelton 代码:

private SSLSocketFactory newSslSocketFactory() {
    try {
        // Get an instance of the Bouncy Castle KeyStore format
        KeyStore trusted = KeyStore.getInstance("BKS");
        // Get the raw resource, which contains the keystore with
        // your trusted certificates (root and any intermediate certs)
        InputStream in = mCtx.getResources().openRawResource(R.raw.evennewer);
        try {
            // Initialize the keystore with the provided trusted certificates
            // Provide the password of the keystore
            trusted.load(in, KEYSTORE_PASSWORD);
        } finally {
            in.close();
        }

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(trusted);

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        SSLSocketFactory sf = context.getSocketFactory();
        return sf;
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

我的 Node.Js 代码:

var config     = {
  key: fs.readFileSync('./ssl/newkey.key'),
 cert: fs.readFileSync('./ssl/newcert.crt')
};
var port = 443;
var server = https.createServer(config, app).listen(port, function(){
console.log("Express server listening on port " + port);
});

并且 openssl 调试返回:

验证返回码:18(自签名证书)

【问题讨论】:

    标签: android node.js ssl https android-volley


    【解决方案1】:

    您可以尝试以下示例代码。希望这会有所帮助!

    private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
        final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
        return new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return originalTrustManager.getAcceptedIssuers();
                    }
    
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        try {
                            if (certs != null && certs.length > 0){
                                certs[0].checkValidity();
                            } else {
                                originalTrustManager.checkClientTrusted(certs, authType);
                            }
                        } catch (CertificateException e) {
                            Log.w("checkClientTrusted", e.toString());
                        }
                    }
    
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        try {
                            if (certs != null && certs.length > 0){
                                certs[0].checkValidity();
                            } else {
                                originalTrustManager.checkServerTrusted(certs, authType);
                            }
                        } catch (CertificateException e) {
                            Log.w("checkServerTrusted", e.toString());
                        }
                    }
                }
        };
    }    
    
    private SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
            throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {
    
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = getResources().openRawResource(keystoreResId);
    
        Certificate ca = cf.generateCertificate(caInput);
        caInput.close();
    
        if (keyStoreType == null || keyStoreType.length() == 0) {
            keyStoreType = KeyStore.getDefaultType();
        }
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);
    
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);
    
        TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
    
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, wrappedTrustManagers, null);
    
        return sslContext.getSocketFactory();
    }
    
    private SSLSocketFactory getSSLSocketFactory_KeyStore(String keyStoreType, int keystoreResId, String keyPassword)
                throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {
    
            InputStream caInput = getResources().openRawResource(keystoreResId);
    
            // creating a KeyStore containing trusted CAs
    
            if (keyStoreType == null || keyStoreType.length() == 0) {
                keyStoreType = KeyStore.getDefaultType();
            }
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    
            keyStore.load(caInput, keyPassword.toCharArray());
    
            // creating a TrustManager that trusts the CAs in the KeyStore
    
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
    
            TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
    
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, wrappedTrustManagers, null);
    
            return sslContext.getSocketFactory();
        }
    

    然后调用两者之一:

    SSLSocketFactory sslSocketFactory = getSSLSocketFactory_KeyStore("BKS", R.raw.androidbksv1, "123456789");
    SSLSocketFactory sslSocketFactory = getSSLSocketFactory_Certificate("BKS", R.raw.androidbksv1_cert);
    

    【讨论】:

    • @AjayShrestha 请稍候,我会尽快在您的问题中发布答案。现在我在手机上上网:-)
    • @BNK 你能告诉我们如何将它与 Volley 结合使用吗?谢谢!
    • @Zain 我在stackoverflow.com/questions/32673568/… 得到了答复。请检查它是否有帮助
    • @BNK 凌空如何实现?
    • 我只遇到过几次错误。以及如何创建放在原始文件夹中的证书文件?
    猜你喜欢
    • 1970-01-01
    • 2013-09-28
    • 2015-11-25
    • 2018-08-05
    • 2019-01-02
    • 1970-01-01
    • 2022-01-06
    • 2017-05-06
    相关资源
    最近更新 更多