【问题标题】:Android - Obtain self-signed server certificate and add to trusted keystoreAndroid - 获取自签名服务器证书并添加到受信任的密钥库
【发布时间】:2017-03-05 22:55:23
【问题描述】:

我的 android 应用程序连接到 用户提供的 URL。在 HTTPS 连接的情况下,如果服务器的证书是由 Android 的 TrustManager 中已经存在的 CA 颁发的,那么一切都很好。

但如果服务器使用自签名证书,我如何在第一次连接时获取该证书并将其存储在 TrustManager 中?

我正在使用OkHttp 库来执行网络任务。我目前的解决方案迫使我在开发过程中将证书添加到应用程序的raw 文件夹中,但这不适用于上述场景。我目前使用的代码如下:

private KeyStore readKeyStore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

    String password = "testPass";

    InputStream is = null;

    try {
        is = activity.getApplicationContext().getResources().openRawResource(R.raw.server_key);
        ks.load(is, password.toCharArray());
    } finally {
        if (is != null)
            is.close();
    }

    return ks;
}

private OkHttpClient getOkHttpClient() throws CertificateException, IOException, KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {

    SSLContext sslContext = SSLContext.getInstance("SSL");
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

    trustManagerFactory.init(readKeyStore());
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(readKeyStore(), "testPass".toCharArray());

    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());

    return new OkHttpClient().setSslSocketFactory(sslContext.getSocketFactory());
}

【问题讨论】:

    标签: android ssl okhttp


    【解决方案1】:

    简单的解决方案

    Here's a code example 的信任管理器回调。从回调中,您可以存储自签名证书或立即接受它们。 但你不应该这样做。通过接受自签名证书,您可能会连接到可以窃取个人数据、安装恶意软件和做其他令人讨厌的事情的虚假或恶意服务器。

    比简单更好的解决方案

    如果服务器提供了您(开发人员)在编译时信任的自签名证书,您可以将证书捆绑到应用程序中,就像您已经在做的那样。如果服务器有 CA 签名证书会更好,但如果你真的需要连接到提供自签名证书的服务器,这将(必须)这样做。

    更好的解决方案

    从不接受运行时的自签名证书。如果您想让您的用户连接到此类服务器,您可以在接受自签名证书之前显示一条警告消息,例如“风险自负”。

    【讨论】:

      【解决方案2】:

      您不应该在第一次连接时添加它。理想情况下,他们应该付费以获得由 CA 签署的正确证书。

      但即便如此,您也可能会发现已安装的 Java 版本不支持的热门新 CA,例如 Let's Encrypt。

      在这些情况下,您可以使用 JVM 的 keytool 手动添加单个证书或新 CA,或者通过标准 Android 机制加载它。

      或者您可以将它们与应用程序捆绑在一起。此示例代码展示了如何使用 Merged TrustStore https://github.com/yschimke/oksocial/blob/master/src/main/java/com/baulsupp/oksocial/security/CertificateUtils.java 加载现有系统证书之外的捆绑证书。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-13
        • 2018-01-24
        • 1970-01-01
        • 2015-08-01
        • 2017-07-12
        • 2014-11-29
        • 1970-01-01
        相关资源
        最近更新 更多