【发布时间】:2021-12-03 05:03:21
【问题描述】:
在深入研究这个问题的过程中,我一直在编辑这个问题。
编辑 我能够将我的 OkHttp 客户端构建到它包含 Client.SSLContext.KeyManager 中的客户端证书和 Client.SSLContext.TrustManager 中的受信任证书的位置
// Create keyManagerFactory with keystore.jks
KeyStore clientStore = KeyStore.getInstance(KeyStore.getDefaultType());
clientStore.load(new FileInputStream(new File("keystore.jks")), storePassword.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientStore, storePassword.toCharArray());
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
// Create trustManagerFactory with default cacerts truststore
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
trustManager = trustManagers[0];
// Create sslContext from keyManagers (from custom keystore with client key) and default trustManagers
sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
sslSocketFactory = sslContext.getSocketFactory();
defaultFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
okClient = new OkHttpClient
.Builder()
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManager)
.build();
但是,我的客户端仍然没有发送我的客户端证书(服务器证书已通过信任库成功验证)。在 ssl 调试日志中获取此信息
No X.509 certificate for client authentication, use empty Certificate message instead
这是我的 SSLContext 在 HttpClient 上的样子。 似乎应该在请求中发送名为“cureskeystore”的客户端证书?
keystore.jks 使用以下命令构建
openssl pkcs12 -export \
-name curesKeyStore \
-in clientCert.crt \
-inkey privateKey.pem \
-certfile clientCert.crt \
-out chain.p12 \
-passout pass:${STORE_PASSWORD}
keytool -importkeystore \
-srckeystore chain.p12 \
-srcstoretype pkcs12 \
-destkeystore keystore.jks \
-deststoretype pkcs12 \
-storepass ${STORE_PASSWORD} \
-srcstorepass ${STORE_PASSWORD} > /dev/null 2>&1
我还尝试使用客户端证书 + -CAfile 使用根证书和中间证书创建商店:
# client cert with CAcerts included
openssl pkcs12 -export -chain \
-in clientCert.crt \
-inkey privateKey.pem \
-out keystore.p12 \
-name p12KeyStore \
-CAfile caCerts.crt \
-caname root \
-passout pass:${STORE_PASSWORD}
keytool -importkeystore \
-srcstoretype PKCS12 \
-destkeystore keystore.jks \
-srckeystore keystore.p12 \
-alias p12KeyStore \
-storepass ${STORE_PASSWORD} \
-srcstorepass ${STORE_PASSWORD}
另一个可能的问题是 CertificateRequest 与我的客户端证书不匹配。
javax.net.ssl|DEBUG|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:671|Consuming CertificateRequest handshake message (
"CertificateRequest": {
"certificate types": [ecdsa_sign, rsa_sign, dss_sign]
"supported signature algorithms": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp521r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha224, rsa_sha224, dsa_sha224, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
"certificate authorities": [redacted, but does not include Entrust]
}
)
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp256r1_sha256
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp384r1_sha384
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for EC
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp521r1_sha512
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha256
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha384
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_rsae_sha512
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha256
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.619 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha384
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pss_pss_sha512
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha256
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha384
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha512
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha256
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for EC
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha224
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_sha224
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha224
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|X509Authentication.java:213|No X.509 cert selected for EC
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.620 EDT|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha1
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|X509Authentication.java:213|No X.509 cert selected for RSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha1
javax.net.ssl|ALL|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|X509Authentication.java:213|No X.509 cert selected for DSA
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha1
javax.net.ssl|WARNING|24|XNIO-1 task-1|2021-10-18 11:07:18.621 EDT|CertificateRequest.java:774|No available authentication scheme
我的证书的签名算法是SHA256withRSA。这和rsa_pkcs1_sha256不一样吗?
另外,我的客户端证书是由 Entrust 签署的,它没有在服务器的 CertificateRequest 的证书颁发机构中列出。
编辑:我向另一台 HTTPS 服务器发出了一些请求,该服务器在其对客户端的 CertificateRequest 中不包含 certificate authorities。我验证 SSL 可以找到预期的客户端证书并按预期将其发送回服务器。因此,这似乎是服务器请求不包括我的 CA 在他们接受的certificate authorities 列表中的问题。联系服务器请求更新。
【问题讨论】:
-
“他们似乎都与自签名证书有关。” - 他们不是。它们还与配置错误的服务器有关,例如不发送所有中间证书。它们还与发送错误证书的服务器有关,因为客户端不使用 SNI。不幸的是,由于没有提供足够的信息来重现或调试问题,因此不知道您的问题是什么。
-
sslContext.init 采用一组信任管理器。如何先将您的自定义管理器传递给它,然后再传递给默认管理器(具有所有标准证书)?或者,您可以将需要信任的根证书导入您自己的自定义信任库。
-
在
No X.509 for client auth之前的调试日志中,应该有一个CertificateRequest消息的解码,显示(取决于Java版本)服务器要求的Cert Authorities:或certificate_authorities:。确保客户端证书链中证书的颁发者名称与服务器所需的 CA 之一完全匹配。 @ewramner+ JSSE 名义上采用一组密钥和信任管理器,但它只使用给定类型的第一个;此 API 旨在允许 PKIX 以外的身份验证形式,但实际上除了 PKIX 之外没有其他身份验证形式。 -
我不使用Postman,也不知道是不是用Java写的,如果是,是否使用标准(JSSE)TrustManager实现。如果没有,即使它不应该发送证书,它也可以轻松发送,并且服务器可能能够验证比它要求的证书更多的证书。我不知道 Postman 是否会显示或记录此信息,但如果不是,除非您使用 TLS1.3,否则您可以使用wireshark 或类似工具在外部看到它。您也可以使用不实现名称检查的
openssl s_client -cert -key手动测试。 -
我还注意到您创建 P12 的命令没有指定任何中间的又名链证书。你确定这个客户证书不需要吗?所有公共 CA 必须至少使用一个,但您没有说是否使用公共 CA;许多私有 CA 也这样做是为了提高根密钥的安全性。如果是这样,服务器可能 询问 根 CA,它发布了(顶部)链证书,该证书应该在您的密钥条目中(不仅仅是在存储中)并发送,但它可能能够重建如果您的客户不发送链本身(这正式违反了 RFC)。