Android OkHttp TLS Mutual Auth - 客户端不向服务器发送证书

时间:2021-02-24 13:41:13

标签: android ssl grpc okhttp tls1.2

我需要一些有关 Android OkHttp 客户端/服务器应用程序的帮助。问题如下:在收到证书请求后,我的 Android 客户端似乎没有向服务器发送任何证书。 这是我的 Android 代码:

private static SSLContext getContext(InputStream keystoreInputStream){
    SSLContext sslContext = null;
    try{
        //==========
        try {
            // The keystore contains the CA cert and the Client cert
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            try {
                keyStore.load(keystoreInputStream, "MYPASS".toCharArray());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    ksIn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            sslContext = SSLContext.getInstance("TLS");
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
            keyManagerFactory.init(keyStore, "MYPASS".toCharArray());
            sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //==========
    }catch (Exception e){

    }
    return sslContext;
}

这是Android客户端(192.168.1.72)和服务器(192.168.1.79)之间的wireshark会话:

Wireshark TLS session - CLIENT CERTIFICATE (empty)

正如你所看到的,服务器发送了一个证书请求,但客户端发送了长度为 0 的证书。你能解释一下我该如何解决这个问题吗?谢谢。

2 个答案:

答案 0 :(得分:1)

我终于发现问题出在我的 KeyStore 和 TrustStore 文件中,它们只是格式错误。 我只是尝试使用这些简单的段落重新生成它们:

  1. 创建一个包含您的客户端证书和密钥的 txt 文件(只需将密钥复制粘贴到证书后即可)。
  2. 生成密钥库: openssl pkcs12 -export -in <GENERATED_TXT_FILE> -out <MY_KEY_STORE>.pkcs12 -name <ALIAS> -noiter -nomaciter
  3. 生成信任库: keytool -import -file <CA_CERT_FILE> -alias <ALIAS> -keystore <MY_TRUST_STORE>

我还提到了 SSLTrustManagerHelper 的这个实现:https://codesandbox.io/s/hidden-waterfall-s0t0m?file=/src/App.js,我把它留在这里,因为我发现它干净且易于理解。

答案 1 :(得分:0)

首先尝试使用像 https://server.cryptomix.com/secure 这样的 URL 的现有设置。它应该打印出您发送的客户端证书。

其次,您可以自己实现 KeyManager 并查看发生了什么,即使它只是装饰 Android KeyManager 并记录调用。

https://github.com/yschimke/okhttp/blob/c2d570dcf9c989a95f49f6b97d5df3488c191f73/regression-test/src/androidTest/java/okhttp/regression/keys/ClientAuthAndroidTest.java#L56

最后,您可以尝试使用 JDK 进行比较。在这种情况下,您可以启用 SSL 日志记录以查看发生了什么,但不要期望 JSSE 和 Android 的 Conscrypt 提供程序之间的行为相同。