需要为SSL配置Tomcat 7

时间:2018-02-22 02:32:04

标签: java ssl tomcat7 x509 keytool

我正在努力为SSL配置Tomcat,并感谢任何帮助。出于我的目的,我需要创建一个根证书和一个由根证书签名的服务器证书。

为了帮助我理解,我将其分为两个步骤:使用openssl创建证书,并将证书导入Tomcat的密钥库。这是我使用openssl和keystore命令的步骤序列。

-- Create certficates --
1. Create CA key in private directory:                                               
openssl genrsa -out CA.key 4096
2. Create CA PEM request using CN <Root Name> and CA key:  
openssl req -key ../private/CA.key -new -out CA.req
3. Create CA PEM using Create CA PEM request:                   
openssl x509 -req -days 365 -in CA.req -signkey ../private/CA.key -sha256 -out CA.pem
4. Create server key (encrypted with password):                      
openssl genrsa -des3 -out server.key 4096
5. Create server PEM request using CN <FQDN of Server>:  
openssl req -new -key server.key -out server.req
6. Create server PEM using Create server PEM request:           
openssl x509 -req -days 3650 -in server.req -signkey ../private/CA.key -out server.pem
7. Export CA certificate as PKCS12 file (possibly not necessary):
openssl pkcs12 -export -inkey ../private/CA.key -in CA.pem -out CA.p12 
8. Export server certificate as PKCS12 file:
openssl pkcs12 -export -inkey ../private/CA.key -in server.pem -out server.p12

-- Install certificates --
9. Add CA PEM to server keystore:
keytool -import -trustcacerts -alias root -file CA.pem -keystore keystore.jks
10. Add server PKCS12 to client keystore:
keytool -import -alias server -file server.p12 -keystore KeyStore.jks

在最后一个命令中,我收到以下错误消息:

keytool error: java.lang.Exception: Input not an X.509 certificate

我不完全理解PEM和PKCS12格式之间的关系以及为什么我需要以PEM格式导入根证书和PKCS12格式的服务器证书 - 也许这就是我出错的地方?

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

主要是欺骗HAProxy SSL termination + client certificate validation + curl / java client

首先,你的#6错了;您不能创建由CA签名的服务器证书,而是具有服务器名称和CA密钥的自签名证书。这就是为什么#8需要配对服务器&#39;带有CA密钥的cert,通常没有意义。在#6中使用-CA-CAkey,在8证书中使用服务器密钥和服务器证书以及最好使用CA证书(仅限)作为CA证书使用-CA - 即:

 openssl pkcs12 -export -in server.pem -inkey server.key -CA CA.pem -out server.p12

其次,正如我现在更新的欺骗中所解释的那样,您可能根本不需要转换为JKS; Java通常可以处理PKCS12。但是如果你这样做,你需要使用-importkeystore,如图所示,这是一个单独的不同操作,而不是-import[cert]

最后,您的部分混淆可能是由于误用了PEM&#39;。 PEM不是一件事;它是一种可用于许多事物的格式,由包含5个连字符的BEGIN行,单词BEGIN,识别数据类型的一个或几个单词以及另外5个连字符组成;然后是一个可选的(并且相当罕见)RFC822样式的头文件;然后是一行或多行base64,它对BEGIN行指定的任何数据进行编码;然后是一个与END类似的行,而不是BEGIN。

PEM可用于证书(以几种格式),密钥(以多种格式),CSR,CRL,OCSP请求和响应,多种格式的消息以及其他可能的东西。您命名的文件&#39; .pem&#39;以PEM格式更准确地证书; &#39; .key&#39;和&#39; .req&#39;您使用的文件也是PEM格式,但不是证书,而是密钥和证书请求(CSR)。证书文件(以PEM或任何其他格式)与PKCS12文件之间的关键区别(原谅双关语)是PKCS12通常包含私钥证书或(通常)a&#39 ;链&#39;几个证书。 (尽管Java9使用 - 可以说是滥用 - PKCS12所以它只能只包含证书;这是非常规的,而且AFAICT不可互操作。)

所有这些PEM文件都具有非PEM等价物,OpenSSL称之为&#39; DER&#39; (虽然&#39;二进制&#39;可能更准确)。您可以在PEM DER中获得证书,但它仍然是证书;你可以在PEM DER中拥有一把钥匙; PKCS12是一个例外;它仅以二进制/非PEM格式支持。虽然并非所有OpenSSL命令都支持PEM和DER。 您的错误消息不是因为尝试&#39; -importcert&#39;非PEM格式的东西,但试图&#39; -importcert&#39;不是特定证书(任何格式)的东西。这就是为什么它说&#39;输入不是X.509证书&#39; - 这意味着输入不包含证书。

通常(此处不相关的极少数例外情况)SSL / TLS服务器需要私钥证书或链;像旧版Tomcat这样的Java SSL / TLS服务器需要Java支持的密钥库私有密钥和证书/链,如上所述,可以是JKS或PKCS12。 (Tomcat 8.5和9将此更改为“JS JSSE和APR OpenSSL的配置”。)如果要导入CA为生成的密钥对发出的证书回复在Java中,特别是在密钥库文件中,您通常需要导入构成该链的多个证书,作为单个链(通常是P7B)或从根开始单独;您可能一直在查看该案例的说明,这不是您在OpenSSL中而不是在Java密钥库中生成密钥对(以及证书)的情况。

SSL / TLS 客户端 OTOH仅需要trust-anchor证书(无密钥),通常是根CA证书。对于由真实&#39;发行的证书。 (公共)CA,包括Java在内的大多数客户端已经内置了公共根CA,但是由于您要创建自己的CA,因此需要将CA证书(仅)分发给您的客户端(可能除了忽略任何错误之外)证书,如openssl s_clientcurl -k)。

最后警告:以这种方式使用OpenSSL生成的证书(因此您的服务器使用它们)在Chrome 58或更高版本(自2017年中期以来)无法工作,因为它现在需要SubjectAltNames aka SAN;看到许多关于此的Q.

答案 1 :(得分:0)

我认为上述答案是正确的,但如果它能帮助找到这个问题的任何人,那么我只是在这里发布我工作的脚本(用提示时使用的密码替换<password> ):

REM Create certficates --
REM 1. Create CA key in private directory:                                               
REM openssl genrsa -out CA.key 4096
REM 2. Create CA PEM request using CN <Root Name> and CA key:  
openssl req -key ../private/CA.key -new -out CA.req
REM 3. Create CA PEM using Create CA PEM request:                   
openssl x509 -req -days 365 -in CA.req -signkey ../private/CA.key -sha256 -out CA.pem
REM 4. Create server key (encrypted with password):                      
openssl genrsa -des3 -out server.key 4096
REM 5. Create server PEM request using CN <FQDN of Server>:  
openssl req -new -key server.key -out server.req
REM 6. Create server PEM using Create server PEM request:           
openssl x509 -req -days 3650 -in server.req -CA CA.pem -CAkey ../private/CA.key -CAcreateserial -CAserial ca.srl -out server.pem
REM 7. Export CA certificate as PKCS12 file (possibly not necessary):
REM openssl pkcs12 -export -inkey ../private/CA.key -in CA.pem -out CA.p12 
REM 8. Export server certificate as PKCS12 file:
openssl pkcs12 -export -in server.pem -inkey server.key -out server.p12 -name server -CAfile CA.pem -caname root

REM -- Install certificates --
REM 9. Add CA PEM to server keystore:
keytool -import -trustcacerts -alias root -file CA.pem -keystore keystore.jks
REM 10. Add server PKCS12 to keystore:
keytool -importkeystore -deststorepass <password> -destkeypass <password> -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass <password> -alias server
REM 11. List keys in keystore
keytool -list -keystore keystore.jks