OkHttp 客户端身份验证无法验证服务器并在同一请求中发送客户端证书
OkHttp client authentication failing to validate server and send client certificate in the same request
我在深入研究时不断编辑这个问题。
编辑
我能够将我的 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
。正在联系服务器请求更新。
好的;你的问题是,当服务器请求你的 client-cert/auth 时,它指定了一个不包括你的证书和链使用的 CA 的 CA 列表,即使与你的证书一起出现-and-chain 服务器接受它。在评论了编写包装器 KeyManager 之后,我意识到测试起来很容易,下面的示例对我来说很有效,可以发送与服务器要求的不同的客户端证书。为了简单起见,我直接使用了 SSLSocket,但是使用相同 SSLContext 或 SSLSocketFactory 的任何东西(比如 OkHttp)都应该可以工作。针对 OpenSSL 命令行在 8u301 中进行了测试(但如果你愿意,我可以检查其他一些),这让我可以请求 CA X 的客户端证书,但是当我从 CA Y 提交证书时,它只记录验证错误而不中止连接。
public class SO69577136KeyManagerIgnoreCAs {
public static void main (String[] args) throws Exception {
// keystore.p12 pw truststore.p12 pw host port [Y: wrap KM to ignore issuers]
KeyStore st = KeyStore.getInstance("PKCS12");
try( InputStream is = new FileInputStream(args[0]) ){ st.load(is,args[1].toCharArray()); }
KeyManagerFactory kf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kf.init(st, args[1].toCharArray());
KeyManager[] km = kf.getKeyManagers();
try( InputStream is = new FileInputStream(args[2]) ){ st.load(is,args[3].toCharArray()); }
TrustManagerFactory tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tf.init(st);
TrustManager[] tm = tf.getTrustManagers();
if( args.length>6 && args[6].startsWith("Y") ){
X509ExtendedKeyManager orig = (X509ExtendedKeyManager)km[0]; // exception if wrong type
km[0] = new X509ExtendedKeyManager(){
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
return orig.chooseClientAlias(keyType, null, socket);
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
// not implemented
return null;
}
@Override
public X509Certificate[] getCertificateChain(String alias) {
return orig.getCertificateChain(alias);
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers) {
// shouldn't actually be used AFAICT but just in case
return orig.getClientAliases(keyType, issuers);
}
@Override
public PrivateKey getPrivateKey(String alias) {
return orig.getPrivateKey(alias);
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers) {
// not implemented
return null;
}
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
return orig.chooseEngineClientAlias(keyType, null, engine);
// could just forward to chooseClientAlias(socket=null), that's what underlying does
}
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
// not implemented
return null;
}
};
}
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(km, tm, null /* default */);
SSLSocketFactory sf = ctx.getSocketFactory();
SSLSocket ss = (SSLSocket) sf.createSocket(args[4], Integer.parseInt(args[5]));
ss.startHandshake();
System.out.println ("successful");
}
}
我在深入研究时不断编辑这个问题。
编辑 我能够将我的 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 上的样子。
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
。正在联系服务器请求更新。
好的;你的问题是,当服务器请求你的 client-cert/auth 时,它指定了一个不包括你的证书和链使用的 CA 的 CA 列表,即使与你的证书一起出现-and-chain 服务器接受它。在评论了编写包装器 KeyManager 之后,我意识到测试起来很容易,下面的示例对我来说很有效,可以发送与服务器要求的不同的客户端证书。为了简单起见,我直接使用了 SSLSocket,但是使用相同 SSLContext 或 SSLSocketFactory 的任何东西(比如 OkHttp)都应该可以工作。针对 OpenSSL 命令行在 8u301 中进行了测试(但如果你愿意,我可以检查其他一些),这让我可以请求 CA X 的客户端证书,但是当我从 CA Y 提交证书时,它只记录验证错误而不中止连接。
public class SO69577136KeyManagerIgnoreCAs {
public static void main (String[] args) throws Exception {
// keystore.p12 pw truststore.p12 pw host port [Y: wrap KM to ignore issuers]
KeyStore st = KeyStore.getInstance("PKCS12");
try( InputStream is = new FileInputStream(args[0]) ){ st.load(is,args[1].toCharArray()); }
KeyManagerFactory kf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kf.init(st, args[1].toCharArray());
KeyManager[] km = kf.getKeyManagers();
try( InputStream is = new FileInputStream(args[2]) ){ st.load(is,args[3].toCharArray()); }
TrustManagerFactory tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tf.init(st);
TrustManager[] tm = tf.getTrustManagers();
if( args.length>6 && args[6].startsWith("Y") ){
X509ExtendedKeyManager orig = (X509ExtendedKeyManager)km[0]; // exception if wrong type
km[0] = new X509ExtendedKeyManager(){
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
return orig.chooseClientAlias(keyType, null, socket);
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
// not implemented
return null;
}
@Override
public X509Certificate[] getCertificateChain(String alias) {
return orig.getCertificateChain(alias);
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers) {
// shouldn't actually be used AFAICT but just in case
return orig.getClientAliases(keyType, issuers);
}
@Override
public PrivateKey getPrivateKey(String alias) {
return orig.getPrivateKey(alias);
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers) {
// not implemented
return null;
}
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
return orig.chooseEngineClientAlias(keyType, null, engine);
// could just forward to chooseClientAlias(socket=null), that's what underlying does
}
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
// not implemented
return null;
}
};
}
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(km, tm, null /* default */);
SSLSocketFactory sf = ctx.getSocketFactory();
SSLSocket ss = (SSLSocket) sf.createSocket(args[4], Integer.parseInt(args[5]));
ss.startHandshake();
System.out.println ("successful");
}
}