未发送JavaSSL相互身份验证证书



我正在开发Tomcat中托管的web应用程序。此应用程序使用需要客户端证书的SOAP WS(托管在IIS上)。我已经准备好了所有的东西,但在生产环境中,握手并不正确。

以下是javax.net.debug=ssl 输出的相关部分

1) 找到客户端证书和私钥

found key for : authentication service client company2
chain [0] = [
[
  Version: V3
  Subject: EMAILADDRESS=john.smith@EXAMPLE1.cz, CN=EXAMPLE1, OU=Web Service App, O=My Company, ST=Czech Republic, C=CZ
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
  Key:  Sun RSA public key, 2048 bits
  modulus: ...... 
  public exponent: 65537
  Validity: [From: Mon Nov 04 17:55:55 CET 2013,
               To: Sun Nov 04 17:55:55 CET 2018]
  Issuer: EMAILADDRESS=peter.smith@EXAMPLE2.cz, CN=CA, OU=Web Service App, O=My Company, L=Prague, ST=Czech Republic, C=CZ
  SerialNumber: [ ...... ]
Certificate Extensions: 4
[1]: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
Extension unknown: DER encoded OCTET string = ...... 

[2]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [ ..... ]
]
[3]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
[EMAILADDRESS=peter.smith@EXAMPLE2.cz, CN=CA, OU=Web Service App, O=My Company, L=Prague, ST=Czech Republic, C=CZ]
SerialNumber: [ .... ]
]
[4]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:false
  PathLen: undefined
]
]
  Algorithm: [SHA1withRSA]
  Signature: .......
]

2) 信任存储初始化

trustStore is: ......
trustStore type is : jks
trustStore provider is : 
init truststore
...
adding as trusted cert:
  Subject: EMAILADDRESS=peter.smith@EXAMPLE2.cz, CN=CA, OU=Web Service App, O=My Company, L=Prague, ST=Czech Republic, C=CZ
  Issuer:  EMAILADDRESS=peter.smith@EXAMPLE2.cz, CN=CA, OU=Web Service App, O=My Company, L=Prague, ST=Czech Republic, C=CZ
  Algorithm: RSA; Serial number: 0x......
  Valid from Mon Nov 04 15:35:23 CET 2013 until Sat Nov 04 15:35:23 CET 2023
...

3) 在WS服务器终结点上找到受信任的证书

Found trusted certificate:
[
[
  Version: V3
  Subject: CN=Thawte SSL CA, O="Thawte, Inc.", C=US
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
  Key:  Sun RSA public key, 2048 bits
  modulus: .....
  public exponent: 65537
  Validity: [From: Mon Feb 08 01:00:00 CET 2010,
               To: Sat Feb 08 00:59:59 CET 2020]
  Issuer: CN=thawte Primary Root CA, OU="(c) 2006 thawte, Inc. - For authorized use only", OU=Certification Services Division, O="thawte, Inc.", C=US
  SerialNumber: [ ..... ]

4) 服务器请求客户端证书

CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
...
<EMAILADDRESS=peter.smith@EXAMPLE2.cz, CN=CA, OU=Web Service App, O=My Company, L=Prague, ST=Czech Republic, C=CZ> 

5) 客户什么都不提供:-(

ServerHelloDone
Certificate chain
ClientKeyExchange, RSA PreMasterSecret, TLSv1
...  

整个过程以WS服务器上的http 403结束(不提供客户端证书的正确行为),握手没有例外。客户端是wsimport生成的javax.xml.ws.Service。

最让我困惑的是,在dev/test环境中,完全相同的证书通过得很好(使用完全相同的信任库和WS客户端)。因此,客户端应用程序和证书似乎运行良好。

也许其他环境中有一些与java相关的故障,或者我遗漏了什么?

非常感谢您的帮助。经过几天的思考,我在这里有点迷路了。

我将附加任何相关的输入,将被要求。

谢谢。

其他信息:

  • 尝试通过浏览器访问Web服务导致证书选择对话框。选择后(使用正确的证书),将显示标准页面"此服务的元数据发布当前已禁用"

我想通了!

问题是,我使用自定义KeyManagerFactory根据SO上的其他问题来选择证书(类似于http://vafer.org/blog/20061010073725/)。我认为在测试环境中一切都很好,只是因为当我将默认SSLContext与自定义KeyManagerFactory一起使用时,它是第一次初始化的。

在生产tho中,全局SSLContext(或类似的东西,对不起我的JAVA noobines)在我的应用程序初始化并插入所需密钥之前被使用和初始化。因此,即使我允许SSLContext访问密钥对(如上所述,在日志中),它在握手过程中也没有使用它。现在,我只需首先调用其他应用程序,就可以在测试环境中重现这一点。

为了解决这个问题,我还将-Djavax.net.keyStore参数设置为指向具有客户端密钥对的存储。因此,strore现在已使用密钥正确初始化。这种解决方法的缺点是显而易见的:tomcat上运行的所有其他应用程序现在都可以访问客户端证书密钥对。我想我可以接受。

最新更新