Tomcat HTTPS 密钥库证书

Posted

技术标签:

【中文标题】Tomcat HTTPS 密钥库证书【英文标题】:Tomcat HTTPS keystore certificate 【发布时间】:2011-01-04 13:08:29 【问题描述】:

使用 SSL 和 Tomcat 时遇到了另一个问题:我配置了一个密钥库,其中包含一个密钥和一个证书(我希望向连接到该站点的客户端提供的服务器证书)。我为信任库做了同样的事情(我将需要客户端身份验证)。

我现在遇到的问题是,当我通过 HTTPS 连接到我的 Tomcat 实例时,提供给我的证书(服务器证书)不是我的实际服务器证书,而是JKS 密钥库。使用 -Djavax.net.debug=ssl 表明它为客户端身份验证提供了正确的 CA,但不是正确的服务器证书。

添加为受信任的证书:
  主题:CN=A
  发行人:CN=A
  算法:RSA;序列号: -
  有效期为 2009 年 11 月 10 日星期二 14:48:31 CET 至 2010 年 2 月 8 日星期一 14:48:31 CET

添加为受信任的证书:
  主题:X
  发行人:X
  算法:RSA;序列号: -
  有效期为 2005 年 1 月 19 日星期三 01:00:00 CET 至 2015 年 1 月 19 日星期一 00:59:59 CET

我已经用占位符替换了实际值。 A = 服务器的域名(但在这种情况下,由于某种原因,这是密钥而不是证书)。 X = VeriSign CA(这应该是正确的)。我有一个现有的证书,我想用它来呈现给客户,我使用 keytool 将它导入到 JKS 密钥库中。

Tomcat 连接器配置:

<Connector port="444" protocol="HTTP/1.1" SSLEnabled="true"
  maxThreads="150" scheme="https" secure="true"
  clientAuth="false" sslProtocol="TLS"     
  keystoreFile="conf/ssl/keystore.jks"
  keystorePass="xx"
  keyAlias="testkey"
  truststoreFile="conf/ssl/truststore.jks"
  truststorePass="xx" />

知道为什么我的 Tomcat 实例没有提供正确的证书吗?

【问题讨论】:

给出 ssl 连接器配置(来自 server.xml) 【参考方案1】:

您的配置应该可以正常工作。

Tomcat's how-to 解释了为获得正确的 JKS 所采取的步骤。

确保您已使用适当的别名 (testKey) 将证书导入 jks

【讨论】:

当我将 keyAlias 设置为密钥库中证书的别名时,Tomcat 将无法正确启动。我假设 keyAlias 参数用于指定密钥,而不是证书。我感觉 Tomcat 永远不会正确地提供我的证书,因为它是单独创建的。现在,我将尝试使用 keytool 而不是 openssl 从头开始​​生成一个全新的证书,看看是否会有所不同。 是的,试试看。可以在 tomcat how-to 中看到,密钥和证书应使用相同的别名。 我之前的尝试失败了。我做错了什么,但我不知道是什么。甚至可以出示现有证书,还是必须使用 keytool 来生成新证书?这令人困惑。 我正在尝试做的与以下问题相同:***.com/questions/1180397/…。只是,我不想生成新证书,我想使用现有的。 一般流程是这样的 - 您生成一个密钥和一个 CSR,然后根据该 CSR,您获得一个证书(您自己或从 VeriSign/GeoTrust/等)并导入它。 【参考方案2】:

问题是(显然 - 我无法真正确认这一点)不可能将先前生成的证书(和匹配的密钥)正确导入 JKS 密钥库并由 Tomcat 正确呈现。

我的问题出现的情况如下:

    我有一个证书文件,它是我使用 OpenSSL 从头开始​​生成的(密钥 + CSR -> 证书),由我自己的 CA 签名。 我希望配置 Tomcat,以便它向连接到我的站点的用户提供此特定证书

我发现可行的解决方案是:

    将现有证书其私钥转换为 DER 格式。例如(使用 OpenSSL):

    对于私钥

    openssl pkcs8 -topk8 -nocrypt -in my_private_key.key -inform PEM -out my_private_key.der -outform DER

    对于实际的签名证书

    openssl x509 -in my_certificate.crt -inform PEM -out my_certificate.der -outform DER

    使用自定义 Java 类将两个 DER 文件导入密钥库(JKS 文件)。

    java ImportKey my_private_key.der my_certificate.der

    我自己没有弄清楚这一点(所有功劳归于最初的发明者)。这个 Java 类的源代码以及更多详细信息可以在 here 和 here 找到。我稍微修改了这个类,以便有一个第三个(或第四个)参数来指定生成的 JKS 文件的输出位置。

最终结果是一个 JKS 密钥库,然后可以在 Tomcat 连接器配置中用作密钥库。上述工具将生成具有默认密码的 JKS 文件和 JKS 文件本身,稍后可以使用 keytool -storepasswdkeytool -keypasswd 更改这些密码。希望这对面临同样问题的人有所帮助。

【讨论】:

+1。第二个链接(agentbob.info)对我有用。它向第一个链接 (comu.de) 没有的密钥库发出密码。 Java 的 keytool 不喜欢更改没有密码的密钥库的密码。此外,您可以指定 tomcat 期望的密钥别名(它是“tomcat”)。 旧的 keytool -import,自 IIRC j5 ~2005 起正式更名为 -importcert,无法导入私钥。您可以使用openssl pkcs12 -export 将 PEM 私钥和匹配证书(以及可选且最好是任何所需的 chain 证书)组合到 PKCS12 中,Java 本身可以读取但某些程序无法读取。 t 使用,在这种情况下,您可以使用 keytool -importkeystore -srcstoretype pkcs12 -deststoretype jks ... 转换为 JKS。 (自 2015 年的 8u60 以来,几乎所有程序都接受 PKCS12。) 然而 Tomcat >= 8.5(这将很快成为唯一受支持的版本)根本不再需要密钥库,它使用了一个新的配置方案,即使是 JSSE 也可以使用 OpenSSL 源 PEM 文件,所以这即将过时。【参考方案3】:

扩展@Bozho 评论,

这真的很关键。 “密钥和购买的证书必须在同一个别名下”

从 CA(Verisign、Digicert 等)购买的 SSL 证书应使用与创建 csr 之前生成的私钥相同的别名导入。使用java keytool将购买的证书导入keystore后,会看到“Certificate reply added to keystore”。

要检查信任链,请使用终端命令 openssl s_client -connect yourdomain.com:443 -showcerts。它从您的证书开始并通向受信任的根 CA。

【讨论】:

以上是关于Tomcat HTTPS 密钥库证书的主要内容,如果未能解决你的问题,请参考以下文章

如何从自签名证书的密钥库中导出私钥

tomcat7下对HTTPS的部署配置

Tomcat 服务器和 HTTP 客户端接受过期的自签名证书

tomcat 不提供中间证书(https)

Tomcat启用HTTPS协议配置过程

在 Tomcat 中配置 SSL/TLS 以支持 HTTPS