0

我有一个测试场景,其中一个名为Root的根证书颁发机构签署了一个名为Intermediate的中间证书颁发机构创建的证书签名请求,该证书颁发机构又签署了一个名为Subject的主题创建的证书签名请求。

我使用 Tomcat 作为我的 Web 服务器,我已将其配置为使用主题密钥存储(其中包含证书、中间证书、主题证书链和主题私钥),我启动它以侦听端口 80 (HTTP) 和 443 (HTTPS)。

我在 Firefox 中安装了证书(作为受信任的证书),然后打开了我的域,这就是我得到的:

subject.usip.me uses an invalid security certificate.
The certificate is not trusted because no issuer chain was provided.
(Error code: sec_error_unknown_issuer)

显然,Firefox 无法验证链或类似的信任。现在,在详细介绍我的配置和我采取的步骤之前:我已经更改了我的 Tomcat 配置,以便它使用中间密钥库而不是使用主题密钥库(中间密钥库包含证书,中间证书链和中间私钥)。使用此配置一切正常。

我使用以下工具:

  • 爪哇:1.7.0_05
  • 雄猫:7.0.29
  • 火狐:14.0.1

我使用粘贴在此处的以下脚本创建有问题的密钥存储(它很长)。任何拥有 Java密钥工具的人都可以运行它(由于 4096 RSA 密钥大小,它可能不会太快运行)。

脚本运行后,我可以验证我的主题密钥存储是否包含完整的信任链(如我所见):

c:\>keytool -list -keystore c:\subject.jks -storepass changeit -rfc

它打印出粘贴在此处的以下(同样,非常冗长)输出。对我来说似乎没问题(至少,经过数小时的挣扎,我似乎看不出有什么问题)。

我像这样通过它的server.xml设置了 Tomcat(遵循这个方法) (除了这个默认注释掉的单个标签之外,我什么都没有改变)。

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
           keystoreFile="c:/subject.jks"
           keystorePass="changeit"
           keystoreType="jks"
           keyAlias="subject"
           keyPass="changeit" />

(在我启动 Tomcat 后,连接到它 - 当它使用主题中间密钥存储时 - 没有记录错误。)

在寻找解决方案时,我发现使用openssl我可以验证我的服务,作为该工具的新手用户,我对我的域运行了以下命令(使用 Cygwin):

$ openssl s_client -connect subject.usip.me:443 -CAfile /cygdrive/c/root.pem -showcerts &> /cygdrive/c/openssl.log

再一次,我在这里粘贴了冗长的输出

它说Verify return code: 24 (invalid CA certificate),这很奇怪,因为它(如我所见)指的是证书。现在,当我说我之前重新配置 Tomcat 以使用中间密钥存储时,我也运行了相同的命令,然后使用Verify return code: 0 (ok). 所以我来宾证书就可以了。

我通过帖子和粘贴提到的域名和子域名是在http://freedns.afraid.org/注册的免费域名,它们每个都指向我当前的地址(我想我会提到它,也许这很重要)。

任何想法我做错了什么?

4

1 回答 1

1

好的,我已经设法弄清楚了。当我生成对我的证书签名请求的回复时,我没有指定一些重要的 X.509 证书扩展。

Java 的keytool文档中有一些关于此的信息。(搜索-ext。)

关键点是正确生成、签署 中间证书

keytool -gencert^
 -alias root^
 -ext BasicConstraints:critical=ca:true,pathlen:0^
 -ext KeyUsage:critical=keyCertSign,cRLSign^
 -infile intermediate.csr^
 -keypass changeit^
 -keystore root.jks^
 -outfile intermediate.pem^
 -rfc^
 -sigalg sha512withrsa^
 -storepass changeit^
 -storetype jks^
 -v

主题证书

keytool -gencert^
 -alias intermediate^
 -ext BasicConstraints:critical=ca:false^
 -ext ExtendedkeyUsage:critical=serverAuth,clientAuth^
 -ext KeyUsage:critical=digitalSignature,keyEncipherment^
 -infile subject.csr^
 -keypass changeit^
 -keystore intermediate.jks^
 -outfile subject.pem^
 -rfc^
 -sigalg sha512withrsa^
 -storepass changeit^
 -storetype jks^
 -v

当我有时间并发布我的完整解决方案时,我会更新我的答案。

更新

我在 GitHub 上建立了一个小示例存储库,其中包含我为生成必要的密钥存储文件、证书等而编写的脚本。我在 Bash 中重新编写了我的脚本,并向其中添加了很多配置参数。它可以在没有任何配置的情况下运行。在这种情况下,它将为root.lvh.meintermediate.lvh.mesubject.lvh.me域创建证书(第二级,lvh.me域默认指向127.0.0.1)。将主题密钥存储与 Tomcat 一起使用并将Root证书安装到 Firefox 将导致与https://subject.lvh.me的经过验证的安全连接(没有其他地方,所以https://intermediate.lvh.me不会验证)。

于 2012-08-19T21:33:59.377 回答