gpt4 book ai didi

java - 相互 SSL - 使用 java 作为客户端时,客户端证书链为空

转载 作者:太空宇宙 更新时间:2023-11-03 14:30:31 28 4
gpt4 key购买 nike

我们正在使用 java 客户端(openJDK 1.8.0) 调用需要相互身份验证的 api。为此,我们使用 Java 标准 JKS 文件作为 keystore 和信任库(包含信任证书和身份证书/私钥的同一文件)。我们用来测试的示例 java 如下::

KeyStore clientKeyStore = KeyStore.getInstance("JKS");
clientKeyStore.load(new FileInputStream("./client.keystore"),
password.toCharArray());

// create a client connection manager to use in creating httpclients
PoolingHttpClientConnectionManager mgr = new PoolingHttpClientConnectionManager();


SSLContext sslContext = SSLContextBuilder.create()
.loadKeyMaterial(clientKeyStore, password.toCharArray())
.loadTrustMaterial(clientKeyStore, null).build();

// create the client based on the manager, and use it to make the call
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(mgr)
.setSslcontext(sslContext)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();


HttpPost httppost = new HttpPost("https://someUrl");

String params = "";
StringEntity param = new StringEntity(params);
httppost.setEntity(param);
System.out.println("Sending request...............");
HttpResponse response = httpClient.execute(httppost);

在作为“serverhello”的最后一步的 SSL 握手期间,服务器通过发出“certificaterequest”来请求客户端的身份 - 请在下面找到请求::

    *** CertificateRequest
Cert Types: RSA, ECDSA, DSS
Supported Signature Algorithms: SHA512withRSA, Unknown (hash:0x6, signature:0x2), SHA512withECDSA, SHA384withRSA, Unknown (hash:0x5, signature:0x2), SHA384withECDSA, SHA256withRSA, SHA256withDSA, SHA256withECDSA, SHA224withRSA, SHA224withDSA, SHA224withECDSA, SHA1withRSA, SHA1withDSA, SHA1withECDSA
Cert Authorities:
<CN=Intermediate CA, OU=ourCA.com, O=ourCA Inc, C=US>

在此之后,我们看到下面的行表明 java 的 keyManager 无法找到由同一签名者签名的任何内容。

*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***

我们已经验证证书存在于 keystore 中并且它是一个有效证书(通过在 Windows 框中打开它,如果它的证书无效则不会打开)。所以我们的 keystore 有一个链:myIdentity >> 由中间 CA 签名 >> 由根 CA 签名

我们尝试过的一些事情(没有任何运气)是:

  • 尝试覆盖 keystoremanager 以返回硬编码别名,即 keystore.jks 中证书的别名
  • 尝试将身份证书和 CA 证书拆分到两个单独的文件中,即单独的 keystore.jks 和 truststore.jks

值得分享的是,如果我们使用 cURL,同样的连接也能正常工作。在 cURL 的情况下,我们必须显式传递客户端证书作为参数(cURL 没有 keystore 的概念)并且我们使用的是 linux 默认 keystore (/etc/pki/tls/certs/ca-bundle.crt)

curl -vvv GET https://api.someone.com/some/path -E /home/certificates/client.test.pem --key /home/certificates/client.test.key

我不确定还有哪些其他细节可以增加值(value),但我很乐意分享所有可能需要的细节(除了我的私钥:-P)

最佳答案

我遇到了和你描述的一样的问题。我遇到的问题是我使用 Java 加载了 keystore :

System.setProperty("javax.net.ssl.keyStore", "/path/key.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pass");

当服务器请求 ClientCertificate 时,所有得到的是:

*** CertificateRequest Cert Types: RSA, DSS Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA384withRSA, SHA384withECDSA, SHA256withRSA, SHA256withECDSA, Unknown (hash:0x4,signature:0x2), SHA224withRSA, SHA224withECDSA, Unknown (hash:0x3,signature:0x2), SHA1withRSA, SHA1withECDSA, SHA1withDSA Cert Authorities: <CN=HB Internal Issuing CA, DC=domainx, DC=hb, DC=bis>*** ServerHelloDone Warning: no suitable certificate found - continuing without client authentication

The solution for this was to load the keystore in a different way as described by:Java SSLHandshakeException "no cipher suites in common"

Basically what I did was to change how I created the SSLContext:

From:

System.setProperty("javax.net.ssl.keyStore", "/path/key.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pass");

System.setProperty("javax.net.ssl.trustStore", "/path/trust.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(null, null, null);

收件人:

// instantiate a KeyStore with type JKS
KeyStore ks = KeyStore.getInstance("JKS");

// load the contents of the KeyStore
final char[] keyPasswd = "pass".toCharArray();
ks.load(new FileInputStream("/path/key.jks"), keyPasswd);

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

keyManagerFactory.init(ks, keyPasswd);

SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(keyManagerFactory.getKeyManagers(), null, null);

然后结果是:

*** CertificateRequestCert Types: RSA, DSSSupported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA384withRSA, SHA384withECDSA, SHA256withRSA, SHA256withECDSA, Unknown (hash:0x4, signature:0x2), SHA224withRSA, SHA224withECDSA, Unknown (hash:0x3, signature:0x2), SHA1withRSA, SHA1withECDSA, SHA1withDSACert Authorities:<CN=HB Internal Issuing CA, DC=domainx, DC=hb, DC=bis>*** ServerHelloDonematching alias: ibmwebspheremq01

关于java - 相互 SSL - 使用 java 作为客户端时,客户端证书链为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53114210/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com