2017-07-31 257 views
1

一点背景请求后:HttpClient的与客户端证书认证

我试图测试结果文件发送到eVpT。这是通过GKV服务器完成的:https://verarbeitung.gkv-kommunikationsserver.de/meldung/extra14.meldung

我们有一个类似的生产配对设置,它发送到同一个GKV服务器。

问题来了

首先我生成一个密钥对,是这样的:

keytool -genkeypair -v -alias "TEST" -validity 1095 -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -keystore TEST.keystore -dname "CN=NAME, OU=BN1234, OU=COMPANY NAME, O=ITSG TrustCenter fuer Arbeitgeber, C=DE" 

利用收集到的密钥存储文件我创建了一个证书请求:

keytool -certreq -alias "TEST" -file TEST.p10 -sigalg SHA256withRSA -keystore TEST.keystore 

这被发送到GKV服务器进行签名,并返回了一个.p7c文件,该文件导入到上述密钥存储文件中:

keytool -import -keystore TEST.keystore -alias TEST -trustcacerts -file TEST.p7c 

密钥存储类型是JKS(如果有的话)。

该请求的设置情况如下:

public HttpResponse send(String request, String serverUrl, boolean isEvptTest) { 
    HttpClient httpClient = new HttpClient(); 
    return httpClient.post(request, serverUrl, new HttpClient.HttpPostCallback() { 
     @Override 
     public void configure(DefaultHttpClient defaultHttpClient, HttpPost httpPost) { 
      try { 
       httpPost.setHeader("Content-Type", "application/octet-stream"); 
       registerHttpsScheme(defaultHttpClient); 
       addProxy(defaultHttpClient); 
      } catch (Exception e) { 
       throw new RuntimeException("could not register https scheme", e); 
      } 
     } 
    }); 
} 

private void addProxy(DefaultHttpClient httpClient) { 
    String proxyHost = System.getProperty(Constants.HTTP_PROXY_HOST_PROPERTY); 
    if (!Util.isEmpty(proxyHost)) { 
     String proxyPort = System.getProperty(Constants.HTTP_PROXY_PORT_PROPERTY); 
     HttpHost proxy = new HttpHost(proxyHost, Integer.parseInt(proxyPort), "http"); 
     httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); 
     log.debug(String.format("added proxy host %s port %s", proxyHost, proxyPort)); 
    } 
} 

private void registerHttpsScheme(DefaultHttpClient httpClient) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { 
    SSLSocketFactory socketFactory = new SSLSocketFactory(testKeyStore, testKeyStoreService.getKeyStorePassword(), trustStore); 
    port = 443; 
    Scheme sch = new Scheme("https", port, socketFactory); 
    httpClient.getConnectionManager().getSchemeRegistry().register(sch); 
} 

在HttpClient的POST方法:

public HttpResponse post(String content, String url, HttpPostCallback callback) { 
    DefaultHttpClient httpClient = null; 
    org.apache.http.HttpResponse response = null; 
    HttpResponse serverResponse = new HttpResponse(); 
    try { 
     httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(url); 
     httpPost.setEntity(new StringEntity(content)); 

     if (callback != null) { 
      callback.configure(httpClient, httpPost); 
     } 

     if (log.isDebugEnabled()) { 
      log.debug(format("will post to url[%s] the following content[%s]", url, content)); 
      Header[] allHeaders = httpPost.getAllHeaders(); 
      for (Header header : allHeaders) { 
       log.debug("header = " + header); 
      } 
     } 

     response = httpClient.execute(httpPost); 
     serverResponse.setStatusCode(response.getStatusLine().getStatusCode()); 
     log.debug(format("server response statuscode[%s]", serverResponse.getStatusCode())); 
     String entity = EntityUtils.toString(response.getEntity()); 
     serverResponse.setResponse(entity); 
     if (log.isDebugEnabled()) { 
      log.debug(format("received response [%s]", entity)); 
     } 
    } catch (Exception e) { 
     log.error(format("error while sending to [%s]", url), e); 
     serverResponse.setResponse(e.getMessage()); 
    } finally { 
     consumeContent(httpClient, response); 
    } 
    return serverResponse; 
} 

这个工程与GKV服务器正常交易,但是当我尝试用测试密钥库所有我得到的是一个403响应。


我遇到我的程序与建议javax.net.debug标志,并得到了以下(如果需要的任何部分更详细请让我知道):

found key for : *1234* 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=*NAME*, OU=*BN1234*, OU=*COMPANY NAME*, O=ITSG TrustCenter fuer Arbeitgeber, C=DE 
    Signature Algorithm: SHA256withRSA, OID = *SOMEID* 
... 

然后是一要添加的所有可信证书的列表,包括:

*.gkv-kommunikationsserver.de 

在做出实际的HTTP POST请求:

http-bio-8080-exec-4, setSoTimeout(0) called 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1 
%% No cached client session 
*** ClientHello, TLSv1.2 
RandomCookie: GMT: 1484796190 bytes = { 224, 120, 124, 66, 118, 48, 83, 225, 119, 151, 135, 164, 71, 96, 51, 216, 132, 136, 223, 123, 66, 151, 254, 6, 198, 88, 86, 67 } 
Session ID: {} 
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA 
*** 

...

http-bio-8080-exec-4, READ: TLSv1.2 Handshake, length = 3043 
*** ServerHello, TLSv1.2 
RandomCookie: GMT: 1484796191 bytes = { 74, 209, 14, 128, 123, 109, 178, 53, 206, 74, 209, 82, 66, 241, 252, 13, 234, 164, 2, 171, 46, 102, 203, 234, 224, 28, 213, 70 } 
Session ID: {154, 66, 0, 0, 252, 124, 28, 13, 62, 10, 104, 127, 66, 84, 189, 234, 174, 203, 170, 168, 194, 0, 146, 12, 98, 164, 135, 5, 176, 186, 95, 180} 
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
Compression Method: 0 
Extension renegotiation_info, renegotiated_connection: <empty> 
*** 

...

*** Certificate chain 
chain [0] = [ 
[ 
    Version: V3 
    Subject: CN=*.gkv-kommunikationsserver.de, O=ITSG GmbH, OU=Systeme und Netze, L=Heusenstamm, ST=Hessen, C=DE 
    Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 

...

*** 
Found trusted certificate: 
[ 
[ 
    Version: V3 
    Subject: CN=*.gkv-kommunikationsserver.de, O=ITSG GmbH, OU=Systeme und Netze, L=Heusenstamm, ST=Hessen, C=DE 
    Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 

...

*** ECDH ServerKeyExchange 
Signature Algorithm SHA1withRSA 
Server key: Sun EC public key, 521 bits 

...

*** ECDHClientKeyExchange 
SESSION KEYGEN: 
PreMaster Secret: 
CONNECTION KEYGEN: 
Client Nonce: 
Server Nonce: 
Master Secret: 
Client MAC write Secret: 
Server MAC write Secret: 
Client write key: 
Server write key: 
... no IV derived for this protocol 
http-bio-8080-exec-4, WRITE: TLSv1.2 Change Cipher Spec, length = 1 

... 然后它开始验证似乎很好的数据。然后由于某种原因,一个新的Hello提出要求:

*** HelloRequest (empty) 
%% Client cached [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384] 
%% Try resuming [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384] from port 62362 
*** ClientHello, TLSv1.2 
RandomCookie: GMT: 1484796208 bytes = { 130, 109, 91, 183, 192, 75, 115, 223, 4, 85, 231, 11, 50, 168, 37, 5, 25, 155, 187, 103, 246, 21, 104, 162, 129, 137, 11, 19 } 
Session ID: {154, 66, 0, 0, 252, 124, 28, 13, 62, 10, 104, 127, 66, 84, 189, 234, 174, 203, 170, 168, 194, 0, 146, 12, 98, 164, 135, 5, 176, 186, 95, 180} 
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA 
Extension renegotiation_info, renegotiated_connection: 39:a7:89:65:54:45:31:c8:c1:bc:93:b0 
*** 

...

*** ServerHello, TLSv1.2 
RandomCookie: GMT: 1484796208 bytes = { 104, 194, 244, 49, 210, 153, 252, 205, 241, 25, 177, 239, 212, 114, 206, 70, 186, 6, 152, 31, 243, 128, 145, 3, 86, 42, 208, 145 } 
Session ID: {158, 32, 0, 0, 233, 255, 55, 252, 77, 3, 17, 171, 9, 23, 239, 78, 0, 229, 23, 91, 244, 92, 163, 129, 33, 72, 196, 250, 199, 121, 51, 85} 
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
Compression Method: 0 
Extension renegotiation_info, renegotiated_connection: 39:a7:89:65:54:45:31:c8:c1:bc:93:b0:f1:24:0e:aa:fc:54:f3:7a:1a:79:26:8e 
*** 

...

*** CertificateRequest 
Cert Types: RSA, DSS, ECDSA 
Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA256withRSA, SHA384withRSA, SHA1withRSA, SHA256withECDSA, SHA384withECDSA, SHA1withECDSA, SHA1withDSA 
Cert Authorities: 
<CN=AddTrust External CA Root, OU=AddTrust External TTP Network, O=AddTrust AB, C=SE> 
<CN=StartCom Certification Authority, OU=Secure Digital Certificate Signing, O=StartCom Ltd., C=IL> 
<CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US> 
<OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US> 
<CN=GlobalSign Root CA, OU=Root CA, O=GlobalSign nv-sa, C=BE> 
<CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE> 
<CN=Microsoft Root Certificate Authority 2010, O=Microsoft Corporation, L=Redmond, ST=Washington, C=US> 
<O=Datenaustausch im Gesundheits- und Sozialwesen, C=DE> 
<CN=Microsoft Root Certificate Authority 2011, O=Microsoft Corporation, L=Redmond, ST=Washington, C=US> 
<CN=Microsoft Root Authority, OU=Microsoft Corporation, OU=Copyright (c) 1997 Microsoft Corp.> 
<CN=Microsoft Root Certificate Authority, DC=microsoft, DC=com> 
[read] MD5 and SHA1 hashes: len = 1336 

...

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

.. 只是我还是这样告诉我的我的客户端证书尚未添加到服务器信任库?

回答

2

几件事情尝试:

  1. 这个CA签发链在您的信任存储您的客户端证书的根源在哪里?如果不是,请添加它,否则它不会协调您的证书的颁发地点,也不会选择它。
  2. 您可以使用-Djavax.net.debug=all运行程序。这会将一吨度的信息转储到您的控制台。它将显示所有加载为可信发布者的证书,握手参数以及服务器和客户端之间的交互,以确定谁必须提供交换内容。

一场旷日持久的讨论后,我们到了问题的根源。除了信托商店发行链的根证书外,Ricco几乎拥有所有必要的一切。

在TLS握手的机制,服务器提供发行机构的列表

*** CertificateRequest 
Cert Types: RSA, DSS, ECDSA 
Supported Signature Algorithms: SHA512withRSA, SHA512withECDSA, SHA256withRSA, SHA384withRSA, SHA1withRSA, SHA256withECDSA, SHA384withECDSA, SHA1withECDSA, SHA1withDSA 
Cert Authorities: 
<CN=AddTrust External CA Root, OU=AddTrust External TTP Network, O=AddTrust AB, C=SE> 
<CN=StartCom Certification Authority, OU=Secure Digital Certificate Signing, O=StartCom Ltd., C=IL> 
<CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US> 
<OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US> 
<CN=GlobalSign Root CA, OU=Root CA, O=GlobalSign nv-sa, C=BE> 
<CN=Baltimore CyberTrust Root, OU=CyberTrust, O=Baltimore, C=IE> 
<CN=Microsoft Root Certificate Authority 2010, O=Microsoft Corporation, L=Redmond, ST=Washington, C=US> 
<O=Datenaustausch im Gesundheits- und Sozialwesen, C=DE> 
<CN=Microsoft Root Certificate Authority 2011, O=Microsoft Corporation, L=Redmond, ST=Washington, C=US> 
<CN=Microsoft Root Authority, OU=Microsoft Corporation, OU=Copyright (c) 1997 Microsoft Corp.> 
<CN=Microsoft Root Certificate Authority, DC=microsoft, DC=com> 

授信引擎将尝试检查,看它是否知道这些发行当局的一个由它的存在信任商店。一旦解决了问题,它将尝试在密钥库中找到第一个在其链中具有匹配证书的privateKeyEntry,然后如果可以恢复私钥,则使用该证书提供后一半的身份验证。有关协议握手的详细信息,请参见RFC 5246

向信托商店Ricco添加与“< O = Datenaustausausch im Gesundheits- und Sozialwesen,C = DE >”相关联的证书后,成功并获得了问题中描述的403错误。

另请注意,此例中的服务器被配置为“需要”而不是“需要”客户端证书身份验证。在“需要”模式下,如果有客户端证书可用,则会显示客户端证书,否则将以正常的TLS连接模式运行。在“需求”模式下,需要呈现客户端证书才能完成TLS连接。

+0

我有这个在我的客户端上的信任: verarbeitung.gkv-kommunikationsserver.de,2016年9月6日,trustedCertEntry, 证书指纹(SHA1): –

+0

确定请按照方案2,因为它会给你最有识之士。 –

+0

我刚刚注意到了一些事情,我希望这能指出你正确的方向。如果您有时间尝试javax.net。调试标志,确定您的httpclient(配置)是否(1)确定适当的privateKeyEntry,然后(2)确定它是否能够解锁私钥。它可能会抑制错误,指出它无法解锁私钥。有一种替代方法来初始化可能涉及的TLS上下文。 –