客户端证书无法从Android运行-如何调试?

客户端证书无法从Android运行-如何调试?,android,ssl,ssl-certificate,bouncycastle,spongycastle,Android,Ssl,Ssl Certificate,Bouncycastle,Spongycastle,我正在尝试为Android应用程序实现客户端证书通信,到目前为止还没有太多成功,而且如果可能的话,这个功能似乎非常困难。我正在实现的完整流程如中所述 我遵循那里的代码和来自那里的代码,或多或少地描述了相同的场景,没有结果 什么不起作用:打开Android客户端和服务器之间的SSL连接(HttpsURLConnection)会导致服务器返回错误消息。 好吧,这403是因为服务器不获取或不信任它获取的客户端证书,我不确定如何调试它 什么有效: 创建PKCS#10请求,将其发送到CA并获得签名的PK

我正在尝试为Android应用程序实现客户端证书通信,到目前为止还没有太多成功,而且如果可能的话,这个功能似乎非常困难。我正在实现的完整流程如中所述

我遵循那里的代码和来自那里的代码,或多或少地描述了相同的场景,没有结果

什么不起作用:打开Android客户端和服务器之间的SSL连接(
HttpsURLConnection
)会导致服务器返回错误消息。
好吧,这403是因为服务器不获取或不信任它获取的客户端证书,我不确定如何调试它

什么有效:

  • 创建PKCS#10请求,将其发送到CA并获得签名的PKCS#7(第7b页)
  • 将接收到的P7B和私钥存储在密钥库中,并将其导出到PKCS#12(第12页)
  • 大多数注释)从设备中拾取P12,在windows上安装,联系服务器并获得一致(200 HTTP-OK)响应
我所做的更改:从和获得的代码示例中,我不得不更改一些内容。我使用的是HttpsURLConnection,而不是OkHttpClient as@而不是那里使用的(但这不重要),我不能像Rich Freedman那样提供证书(他有证书,我通过PKCS#10和#7获得),所以我创建了一个CustomTrustManager,它将信任服务器的证书,出于这个原因,我使用了SpongyCastle(v1.5.0.0,如果有必要,设置为插入0的提供程序)并且也不会持久化证书,但所有操作都在内存中完成

问题是下一步该怎么办:

  • 我如何知道服务器期望的是什么(客户端证书)
  • 如何判断哪些客户端证书(如果有)正在发送到服务器
  • 通常如何调试此场景?(代理(如Fiddler)对底层SSL没有用处)

谢谢!

这不是一个好答案,但这里的内容太多,无法作为评论发布

对于日志记录,您可以创建自己的
X509KeyManager
,它使用从
KeyManagerFactory
获得的普通密钥管理器:

@DebugLog
注释来自Jake Wharton创建的Hugo库。它打印函数参数及其返回值。您可以使用普通的Log.d或任何您想要的

例:

并使用它初始化
SSLContext

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password);

final X509KeyManager origKm = (X509KeyManager) kmf.getKeyManagers()[0];
X509KeyManager km = new MyKeyManager(origKm);

SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(new KeyManager[]{km}, tmf.getTrustManagers(), null);

您将看到调用了哪个方法,参数是什么(从serwer certificate获得),以及keymanager返回了哪个证书和私钥。

这不是一个好答案,但这里的内容太多,无法作为注释发布

对于日志记录,您可以创建自己的
X509KeyManager
,它使用从
KeyManagerFactory
获得的普通密钥管理器:

@DebugLog
注释来自Jake Wharton创建的Hugo库。它打印函数参数及其返回值。您可以使用普通的Log.d或任何您想要的

例:

并使用它初始化
SSLContext

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password);

final X509KeyManager origKm = (X509KeyManager) kmf.getKeyManagers()[0];
X509KeyManager km = new MyKeyManager(origKm);

SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(new KeyManager[]{km}, tmf.getTrustManagers(), null);
您将看到调用了哪个方法,参数是什么(从serwer证书获得),以及keymanager返回了哪个证书和私钥