【发布时间】:2014-04-11 17:50:44
【问题描述】:
我以前问过这个问题,但没有得到任何帮助。我取得了一些进展,但又遇到了一个新错误。
我必须使用保存密钥对和 CA 证书的安全设备。当应用程序与需要相互身份验证的服务器建立 TLS 连接时,我现在必须使用此设备。我有一个能够与安全设备通信的“KeyPair”类。
我的问题是,当建立 ssl 连接时,客户端上出现错误“tlsv1 alert unknown ca”,服务器上出现“SSL3_GET_CLIENT_CERTIFICATE:no certificate returned”。 我的调试日志显示 SSL 上下文确实将我的对象作为信任管理器进行查询。首先我的 checkServerTrusted() 函数被调用,它通过了。接下来调用 chooseClientAlias() 函数,然后调用带有客户端别名的 getPrivateKey() 函数。此时我从设备中提取私钥并将其返回。接下来调用函数 getCertificateChain(),我在一个数组中获取并返回匹配的证书及其签名者 CA。我的调试输出显示证书返回为:
Subject DN: CN=be2576a357228b303189ab62bd2497807d2276493ddfc6fd037a0c8fc6e9ac9a,C=YY,E=a@b.com
Issuer DN: O=myCompany,E=email@mydomain.net,L=myCity,ST=myState,C=XX,CN=LJB
Serial Num = 3877882041
Subject DN = O=myCompany,E=email@mydomain.net,L=myCity,ST=myState,C=XX,CN=LJB
Issuer DN = O=myCompany,E=email@mydomain.net,L=myCity,ST=myState,C=XX,CN=LJB
Serial Num = 10069430368951295741
SSL 连接会在出现上述错误之前暂停。
我已扩展“KeyPair”类以充当密钥和信任管理器,如下所示:
public class Keypair implements X509KeyManager, X509TrustManager
在这个类中,我重写了这些管理器的所有函数,以查看何时调用什么。我的应用程序将始终是与服务器工作的客户端。
因此,在创建此类对象期间,并且在设备上的密钥对的所有测试成功之后,我创建了一个使用特定密钥对的 SSL 上下文。目前设备上只有一对密钥。我用,...
sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(new KeyManager[] {this}, new TrustManager[] {this}, new SecureRandom());
稍后任务将使用此对象创建到服务器的连接
protected boolean Connect(String host, int port) {
SSLSocketFactory factory = getKeypair().getSecureSocketFactory();
socket = (SSLSocket) factory.createSocket(host, port);
:
}
getSecureSocketFactory() 函数仅从密钥对类对象返回 sslCtx.getSocketFactory()。
我搜索了很多并看到了创建工厂等的代码,但没有一个能够帮助我。我不想创建任何密钥库——这就是设备的目的。
那么错误指的是哪个“CA”?服务器证书也是由上面的 CA 直接签名的。如果我不需要客户端进行身份验证,则连接有效。我正在使用 Android 4.1.2 的手机进行测试。
跟进:我确定我的问题在于我的 getCertificateChain() 函数。我只包括从安全设备检索的公共和 CA 证书。它永远不应使用 Android 附带的任何证书。那么,任何人都可以给我一些关于归还我的链条的规则的指示吗?我对“链”的理解是否正确:这必须是与私钥匹配的证书以及直到主 CA(自签名)的所有证书?”
【问题讨论】:
-
'tlsv1 alert unknown ca' 在尝试验证服务器证书时。 CA是指Server的证书。
-
服务器证书也是上面的CA直接签名的,是哪个CA?
-
CA 证书是我的问题中显示的具有相同主题和颁发者的证书。它已经签署了我设备上的证书和服务器证书。
-
上面列出的 CA 似乎不是与操作系统打包的有效 CA。 CA 应该在设备上是已知的,然后才能解析。请参阅 [此处][1] 以获取当前可用于您的设备的 CA 列表。您可以通过在设备的安全设置中配置这些来手动添加自己的 CA。 [1]:stackoverflow.com/questions/3777058/…
-
重点是:CA 也是从持有密钥对的安全设备中读取的。我的信任经理必须使用它。该应用程序从不使用默认安装的 CA 或证书。
标签: java android sockets ssl certificate