有多个匹配证书时,如何选择SSL客户端证书?
这不是设计上应该发生的事情,但是出于安全考虑,我想知道,如果有多个证书与某个CA签署的要求相匹配,那么如何将“正确的”证书发送到服务器?
我正在使用一个简单的SSL JAVA示例客户端,连接到Apache HTTPD。
我尝试用4个证书进行测试,每次删除选择的证书,并记下下一个是谁。除了证书的“
sha256”的词典顺序之外,我找不到合理的逻辑(即日期,别名等)。在我看来这不太可能…
该示例客户端的操作类似于
System.setProperty("javax.net.ssl.keyStore","device.p12"); System.setProperty("javax.net.ssl.keyStorePassword","password");
System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
System.setProperty("javax.net.ssl.trustStore","truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword","password");
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSock = (SSLSocket) factory.createSocket("87.69.60.100",443);
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sslSock.getOutputStream(), "UTF8"));
wr.write("GET /lather HTTP/1.1\r\nhost: 87.69.60.100\r\n\r\n");
wr.flush();
并且Apache配置有
SSLCACertificateFile rootCA.crt SSLVerifyClient require
我找不到相关的文档来回答这个问题。我也想知道-Apache是否有可能以某种方式转发多个证书链?(例如,行为不端的客户发送的邮件很奇怪)。
谢谢!
回答:
需要客户端身份验证的服务器将发送可接受的证书类型列表,以及可能的可接受的CA列表。默认情况下,您的Java客户端然后应用以下算法:
- 对于服务器接受的每种证书类型(RSA,DSA,EC),在密钥库中查找使用指定算法生成的所有公钥/私钥对
- 如果服务器发送了可接受的CA列表,请删除其证书链中列表中不包含任何CA的所有密钥对。
- 如果剩余至少一对密钥对,请选择与第一个对应的私钥;否则,请返回到步骤1以获取下一个密钥类型。
客户端证书选择算法未在RFC
5246中指定,但是Java的简单默认实现似乎是合理的,如果EJP指出将来可能会进行更改。特别地,“第一个”是非常随机的-
凭据当前存储在中Map
,因此它将取决于条目集的迭代顺序。而且,这些KeyManager
实现是可插入的,并且OpenJDK提供了一个“
NewSun”实现,该实现通过传递security属性来激活ssl.KeyManagerFactory.algorithm=NewSunX509
。第二个步骤还将考虑客户端证书的keyUsage和extendedKeyUsage属性,以及有效期。
如果您需要保证从可能的列表中发送的证书,并且发现默认行为对您不利,那么最好的选择是手动创建一个单项密钥库,并使用它来初始化SSLContext
或编写您的证书。自己X509KeyManager
做你想要做的事情chooseClientAlias
,例如在回答这个问题或这个问题时。
以上是 有多个匹配证书时,如何选择SSL客户端证书? 的全部内容, 来源链接: utcz.com/qa/417854.html