我有一个测试场景,一个名为 Root 的根证书颁发机构签署一个由名为 Intermediate 的中间证书颁发机构创建的证书签名请求,后者又签署证书由名为主题的主题创建的签名请求。
我使用Tomcat作为我的Web服务器,并且我已将其配置为使用 Subject 密钥存储区(其中包含 Root 证书, Intermediate 证书,主题证书链和主题私钥),我启动它来侦听端口80(HTTP)和443(HTTPS)。
我在Firefox中安装了 Root 证书(作为可信证书),我点击了我的域名,这就是我得到的:
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配置,以便它使用 Intermediate 密钥存储而不是使用 Subject 密钥库(中间密钥库包含根证书,中间证书链和中间私钥)。使用此配置一切正常。
我使用以下工具:
I create the key stores in question with the following script pasted over here(这很长)。任何拥有Java keytool 的人都可以运行它(由于4096 RSA密钥大小,它可能不会太快运行。)
脚本运行后,我可以验证我的主题密钥库是否包含完整的信任链(正如我所看到的):
c:\>keytool -list -keystore c:\subject.jks -storepass changeit -rfc
It prints out the following (again, quite lengthy) output which is pasted over here。对我来说似乎没问题(至少,经过数小时的挣扎,我似乎无法开始看到它出现任何问题)。
我通过它的 server.xml 设置了Tomcat(following this how-to)(除了这个单独的标签,我没有更改,默认情况下是注释掉的)。
<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后,连接到它 - 当它使用 Subject 或 Intermediate 密钥存储区时 - 没有记录错误。)
在寻找解决方案时,我发现使用 openssl 我可以验证我的服务,作为该工具的新手用户,我对我的域运行了以下命令(使用Cygwin):
$ openssl s_client -connect subject.usip.me:443 -CAfile /cygdrive/c/root.pem -showcerts &> /cygdrive/c/openssl.log
然而,I've pasted the lengthy output over here。
它表示Verify return code: 24 (invalid CA certificate)
,这是奇怪的,因为它(如我所见)指向 Root 证书。现在,当我说我重新配置Tomcat之前使用 Intermediate 密钥存储区时,我也运行了同样的命令,然后用Verify return code: 0 (ok)
检出。所以我访客 Root 证书没问题。
我通过帖子和贴片提到的域名和子域名是http://freedns.afraid.org/注册的免费域名,每个域名都指向我当前的地址(我以为我会提到它,也许这很重要)。
任何想法我做错了什么?
答案 0 :(得分:1)
There is some info on this in Java's keytool documentation。 (搜索-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
当我有时间并发布完整的解决方案时,我会更新我的答案。
I've set up a little example repository at GitHub,其中包含我为生成必要的密钥库文件,证书等而编写的脚本。我在Bash中重写了脚本,并为其添加了许多配置参数。它可以在没有任何配置的情况下运行。在这种情况下,它将为 root.lvh.me , intermediate.lvh.me 和 subject.lvh.me 域创建证书( the second level, lvh.me domain points to 127.0.0.1 by default)。将 Subject 密钥库与Tomcat一起使用并将 Root 证书安装到Firefox中将导致与 https://subject.lvh.me <的验证,安全连接/ em>(以及其他任何地方,因此 https://intermediate.lvh.me 将无法验证)。