【问题标题】:Log the SSL Certificate programmatically以编程方式记录 SSL 证书
【发布时间】:2019-11-12 14:58:29
【问题描述】:

我有 2 台设备无法连接到我的 TLS v1.2 端点。所有其他设备似乎都可以,包括浏览器、PostMan 和 iOS 设备。

这些设备运行的是 Android 5 和 7(因此应该支持 TLS v1.2 不会有问题)。

注意:这不是自签名证书。它由亚马逊签署。

立即想到的是:

  1. Android 碎片 - 可能是设备(一个是 Kindle Fire 7) 没有在操作系统中包含正确的证书。它不会 设备制造商第一次做出奇怪的决定 这会破坏功能。

  2. API 正在通过代理访问,而实际上一个中间人,被正确检测到。


修复 (1) 意味着捆绑我们的证书,并在我们的证书过期时导致常见问题。

我希望用户安装一个调试版本,以确认 (1) 还是 (2) 是问题所在。这样的构建将检查服务器/代理提供的 SSL 证书,并将其记录回给我。


网络框架:

  • 改造 v2.3.0
  • OkHttp v3.9.1

问题:

如何检查设备在访问我的端点时看到的 SSL 证书信息?


根据comment from @SangeetSuresh更新:

原来有 2 个不同的异常被抛出。

Kindle Fire 7" 平板电脑(KFAUWI,OS 5.1.1)正在抛出我已经开始调查的那个,这个问题的重点是。即基本的 SSL 故障。

java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.
       at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:331)
       at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:232)
       at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:114)

LG 设备(LG-SP200,OS 7.1.2)的连接已被对等方关闭,如果此处未解决,则应在新问题下解决:

javax.net.ssl.SSLHandshakeException: 
    Connection closed by peer
       at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(NativeCrypto.java)
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360)
       at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:299)

【问题讨论】:

  • TLS 1.2 仅支持 Android 4.1 及更高版本。此外,在运行 5.0 之前的设备上默认禁用它
  • @Christopher 注意到并已经在我身边检查过。 OkHttpRetrofit 实际上在旧设备上为我解决了这个问题。现在只有 Android 5 和 7 设备出现故障。
  • 那么你能吸引什么? OkHttp 响应?在这种情况下,我认为应该可以从response.handshake().peerCertificates() 获得信息。
  • 我不知道。您可以让您的调试应用只信任所有证书并检查您收到的内容。
  • 继续吧。由于您有可用的测试代码,因此您将能够提出比我更好的答案。

标签: android ssl-certificate


【解决方案1】:

Robby Cornelissen 提供 the basic answer in a comment 引用 OkHttp Response:

信息应该可以从 response.handshake().peerCertificates().

实现了一个简单的Interceptor 来检查证书,给定一个有效的握手:

private static class SslCertificateLogger implements Interceptor {

    public static final String TAG = "SSL";

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response;
        try {
            response = chain.proceed(request);
        } catch (Exception e) {
            Log.d(TAG, "<-- HTTP FAILED: " + e);
            throw e;
        }

        Handshake handshake = response.handshake();
        if (handshake == null) {
            Log.d(TAG, "no handshake");
            return response;
        }


        Log.d(TAG, "handshake success");
        List<Certificate> certificates = handshake.peerCertificates();
        if (certificates == null) {
            Log.d(TAG, "no peer certificates");
            return response;
        }

        String s;
        for (Certificate certificate : certificates) {
            s = certificate.toString();
            Log.d(TAG, s);
        }

        return response;
    }
}

这将按正常方式添加到OkHttpClient

OkHttpClient.Builder builder = new OkHttpClient.Builder()
        .addInterceptor(new SslCertificateLogger())
        .build();

A similar solution 是由 Sangeet Suresh 提出的,它引用了 Retrofit Response 对象:

response?.raw()?.handshake()我想这会对你有所帮助

这里的重要信息是 Retrofit 以这种方式提供对原始 OkHttp 响应的访问权限。

这不会在Interceptor 中使用,而是在更高级别,在实际的改造处理代码中,在从 API 获得改造 Response&lt;&gt; 之后。

将他的 Kotlin 解决方案转换回 Java 可能会产生如下结果:

okhttp3.Response raw = httpResponse.raw();
if (raw != null) {
    Handshake handshake = raw.handshake();
    if (handshake != null) {
        List<Certificate> certificates = handshake.peerCertificates();
        if (certificates != null) {
            for (Certificate certificate : certificates) {
                Log.d(TAG, certificate.toString());
            }
        }
    }
}

如果handshake() 不为空,即握手成功时,两种解决方案都可以正常工作。

鉴于这是对失败握手的调查,需要进一步的步骤来“信任所有证书”(仅限 NB 调试版本!)。

这已经被记录了很多次 - 这是一个这样的版本:

【讨论】:

  • 今天这个握手对象救了我的命!我正在寻找一个拦截器来检查来自服务器的证书,哇,我现在得救了!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-09-29
  • 2011-09-11
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
相关资源
最近更新 更多