tomcat不提供中间证书(https)

Hei*_*nzi 25 https tomcat openssl certificate keystore

我使用openssl可执行文件在控制台上创建了一个密钥和一个csr.然后我将csr发送到CA并获得了证书.现在我想将它导入tomcat.

所以我用我的密钥和我的证书创建了一个PKCS#12文件:

openssl pkcs12 -export -in mycert.cert -inkey mykey.pem -out key_and_cert.p12
Run Code Online (Sandbox Code Playgroud)

然后创建一个包含它的密钥库:

keytool -importkeystore -deststorepass [password] -destkeystore keystore.jks -srckeystore key_and_cert.p12 -srcstoretype PKCS12 -srcstorepass [password]
Run Code Online (Sandbox Code Playgroud)

然后我导入中间证书chain.crt:

keytool -import -trustcacerts -alias root -file chain.crt -keystore keystore.jks
Run Code Online (Sandbox Code Playgroud)

这里输出"keytool -keystore keystore.jks -list":

Keystore-Typ: JKS
Keystore-Provider: SUN

Ihr Keystore enthält 2 Einträge.

root, 14.11.2011, trustedCertEntry,
Zertifikatsfingerabdruck (MD5): [fingerprint]
1, 14.11.2011, PrivateKeyEntry, 
Zertifikatsfingerabdruck (MD5): [fingerprint]
Run Code Online (Sandbox Code Playgroud)

tomcat server.xml包含:

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" URIEncoding="UTF-8" compression="on"
           sslProtocol="TLS"
           keystoreFile="/[absolute-path]/keystore.jks"
           keystorePass="[password]" />
Run Code Online (Sandbox Code Playgroud)

当我重新启动tomcat时,它在catalina.out中没有记录任何错误,一切似乎都没问题.但是当我运行firefox时,它会报告

[domain] uses an invalid security certificate.
The certificate is not trusted because no issuer chain was provided.
(Error code: sec_error_unknown_issuer)
Run Code Online (Sandbox Code Playgroud)

运行"openssl s_client -connect [domain]:443 -showcerts"返回

CONNECTED(00000003)
depth=0 C = DE, OU = Domain Control Validated, CN = [domain]
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = DE, OU = Domain Control Validated, CN = [domain]
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = DE, OU = Domain Control Validated, CN = [domain]
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/C=DE/OU=Domain Control Validated/CN=[domain]
   i:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA - G2
-----BEGIN CERTIFICATE-----
[certificate from mycert.cert]
-----END CERTIFICATE-----
---
Server certificate
subject=/C=DE/OU=Domain Control Validated/CN=[domain]
issuer=/C=BE/O=GlobalSign nv-sa/CN=GlobalSign Domain Validation CA - G2
---
No client certificate CA names sent
---
SSL handshake has read 1777 bytes and written 289 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: [session-id]
    Session-ID-ctx: 
    Master-Key: [master-key]
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1321268519
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
Run Code Online (Sandbox Code Playgroud)

我认为tomcat虽然知道但不提供中间证书.我该怎么做才能让tomcat提供它?

附加信息:导入pkcs12证书时,没有证书链错误,因为-importkeystore命令不检查链.我还尝试先导入中间证书,然后调用-importkeystore.我得到了相同的结果.

编辑:我只是尝试了另一种方法,直接在PKCS#12证书中插入链,并得到以下错误:

$ openssl pkcs12 -export -CAfile chain.pem -in mycert.cert -inkey mykey.pem -out key_and_cert.p12 -name tomcat -chain
Error unable to get issuer certificate getting chain.
Run Code Online (Sandbox Code Playgroud)

但是连锁证书还可以:

$ openssl verify chain.pem
chain.pem: OK
Run Code Online (Sandbox Code Playgroud)

小智 13

我必须通过查找发行者的根证书然后将中间证书放在同一文件中来创建CA文件.然后我跑了:

openssl pkcs12 -export -chain -inkey mykey.key -in mye.crt -name "tomcat" -CAfile intermediate_plus_root.crt -out key_and_cert.p12

  • 我使用了这种方法,但收到了一个错误:"错误无法获得颁发者证书获取链." 所以我按照我在网上找到的一些建议做了:cat PrimaryCA.pem /etc/ssl/certs/ca-certificates.crt SecondaryCA.pem> intermediate_plus_root.crt.重新运行以上,解决了这个问题. (3认同)

Man*_*ner 8

在一些评论中甚至提出了一个更简单的解决方案(不在/ etc/ssl/certs中保存根证书和中间证书)

首先复制文件夹中所有需要的根证书和中间证书(在我们的示例中,文件夹是'〜/ certs',我们的两个证书名为'PrimaryCA.pem'和'SecondaryCA.pem'):

mkdir ~/certs
mv PrimaryCA.pem ~/certs/PrimaryCA.pem
mv SecondaryCA.pem ~/certs/SecondaryCA.pem
Run Code Online (Sandbox Code Playgroud)

然后'c_rehash'文件夹:

c_rehash ~/certs
Run Code Online (Sandbox Code Playgroud)

现在,certs文件夹将包含两个名为"{hash-value}.{n}"的新符号链接,其中{hash-value}是一个8符号哈希值,{n}是一个整数.如果是这种情况,则继续执行以下命令,使用"-CApath"创建.p12,而不是将证书复制到/ etc/ssl/certs:

openssl pkcs12 -export -in cert.pem -inkey key.key -out key_and_cert.p12 -chain -CApath ~/certs
Run Code Online (Sandbox Code Playgroud)

最后将其转换为jks,因为Heinzi在他的回答中已经完美地描述了:

keytool -importkeystore -deststorepass [password] -destkeystore keystore.jks -srckeystore key_and_cert.p12 -srcstoretype PKCS12 -srcstorepass [password]
Run Code Online (Sandbox Code Playgroud)


Hei*_*nzi 6

最后,我得到了它的工作.它不是一个干净的解决方案,但它的工作原理.我将中间证书添加到我的本地/ etc/ssl/certs然后调用

openssl pkcs12 -export -in cert.pem -inkey key.key -out key_and_cert.p12 -chain
Run Code Online (Sandbox Code Playgroud)

由此产生的pkcs12证书我通过转换为jks

keytool -importkeystore -deststorepass [password] -destkeystore keystore.jks -srckeystore key_and_cert.p12 -srcstoretype PKCS12 -srcstorepass [password]
Run Code Online (Sandbox Code Playgroud)

此结果文件现在似乎可以正常工作,tomcat还将证书链传递给在/ etc/ssl/certs目录中没有中间证书的客户端.但我认为必须有一种方法,而无需更改/ etc/ssl/certs.

  • 我发现我需要将`-certfile [intermediate cert]`添加到`pkcs12 -export`命令中.这样,我获得了自己的证书以及某些客户所需的中间证书. (4认同)
  • 请注意,您可以直接将PKCS#12(.p12)文件用作Java中的密钥库:在Apache Tomcat连接器配置中使用`PKCS12`存储类型(`keystoreType ="PKCS12"`). (2认同)
  • 请注意,openssl命令应在提示时提供导出密码,或者使用-passout参数提供,因为以下keytool命令不能与空白srcstorepass一起使用. (2认同)

Gau*_*cho 6

它适用于我使用APR.请参阅http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support_-_APR/Native

  <Connector port="3573" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
               SSLCertificateFile="/my/pem/encoded/certificate/file"
               SSLCertificateKeyFile="/my/pem/encoded/certificate/private_key"
               SSLPassword="yourKeyFilePassword"
               SSLCertificateChainFile="/my/pem/encoded/certificate/authorities/file"
               />
Run Code Online (Sandbox Code Playgroud)