编辑我能够构建我的 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();
Run Code Online (Sandbox Code Playgroud)
但是,我的客户端仍然没有发送我的客户端证书(服务器证书已通过信任存储区成功验证)。在 ssl 调试日志中获取此信息
No X.509 certificate for client authentication, use empty Certificate message instead
Run Code Online (Sandbox Code Playgroud)
这是我的 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
Run Code Online (Sandbox Code Playgroud)
我还尝试使用客户端证书 +-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}
Run Code Online (Sandbox Code Playgroud)
另一个可能的问题是证书请求与我的客户端证书不匹配。
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
Run Code Online (Sandbox Code Playgroud)
我的证书的签名算法是SHA256withRSA. 那不是一样吗rsa_pkcs1_sha256?另外,我的客户端证书是由 Entrust 签名的,该证书未在服务器的 CertificateRequest 的证书颁发机构中列出。
编辑:我向不同的 HTTPS 服务器发出了一些请求,该服务器未包含certificate authorities在向客户端发出的证书请求中。我验证了 SSL 可以找到预期的客户端证书并将其按预期发送回服务器。因此,这似乎是服务器请求的问题,未将我的 CA 包含在其接受的列表中certificate authorities。联系服务器请求更新。
好的; 它已经开发了你的问题是,当服务器请求你的客户端证书/身份验证时,它指定的 CA 列表不包括你的证书和链使用的 CA,即使在提供你的证书时也是如此-and-chain 服务器接受它。在评论了编写包装器 KeyManager 后,我意识到测试起来很容易,下面的示例可以让我发送与服务器要求的不同的客户端证书。为了简单起见,我直接使用了 SSLSocket,但是任何使用相同 SSLContext 或 SSLSocketFactory 的东西(比如 OkHttp)都应该可以工作。在 8u301 中针对 OpenSSL 命令行进行了测试(但如果需要,我可以检查其他一些),这让我可以请求 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");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1240 次 |
| 最近记录: |