在本教程中,您将学习如何在 Apache Tomcat 上安装 SSL 证书,方法是使用 Java 的keytool工具,然后在server.xml中配置 HTTPS 连接器。如果您尚未生成 CSR,第一部分会向您展示具体方法。
我们还录制了一个视频,带您了解整个过程。您可以观看视频、阅读说明,或两者结合。您可以在下方观看视频。
为 Tomcat 生成 CSR 代码
CSR 全称是 Certificate Signing Request(证书签名请求),是一段包含您域名和组织当前信息的文本块。每位购买商业 SSL 证书的用户都必须向证书颁发机构(即 SSL 提供商)提交 CSR,以通过验证并获得证书。如果 CSR 中的信息有误,CA 将无法为其签名。
在 Tomcat 上,CSR 是通过 keytool 从 Java keystore 中创建的,同一个 keystore 中也保存着安装过程中您将重新使用的私钥。您有两个选择:
- 使用我们的CSR 生成器自动创建 CSR。
- 按照我们的分步教程在 Tomcat 上生成 CSR操作。
重要提示:请记住生成 CSR 时使用的keystore 文件和别名(alias)。稍后您需要将已签名的证书导入回这个确切的别名,因为对应的私钥就保存在那里。
证书颁发机构验证您的请求并发送 SSL 文件后,请继续进行以下安装步骤。
在 Tomcat 中安装 SSL 证书
Tomcat 安装分为两个阶段:首先将证书链和已签名的证书导入已经包含您私钥的 keystore 中,然后在server.xml中配置 HTTPS 连接器以使用该 keystore。
步骤一:准备您的 SSL 证书文件
您的证书颁发机构会将文件通过邮件发送到您提供的地址,通常以 ZIP 压缩包的形式。请解压该文件。根据 CA 的不同,文件可能以以下两种格式之一到达:
- PKCS#7:单个.p7b(或.cer)文件,其中已经包含了您的证书以及根证书和中间证书。
- PEM:多个独立文件,通常包括您的服务器证书.crt文件,以及独立的root.crt和intermediate.crt文件。
将解压后的文件上传到服务器,放入您生成 CSR 时所用 keystore 所在的同一目录(下文称为example.jks)。确定您的文件格式后,按对应说明进行操作。
如果您是在别处生成的 CSR,因此私钥是一个独立的文件,而不是 example.jks 中的一个条目?可以跳过 keytool:将 PEM 转换为 PKCS#12,将证书、证书链和私钥打包成一个 .p12 文件,然后在步骤三中通过 certificateKeystoreType=”PKCS12″ 引用该文件。
步骤二:将证书导入您的 keystore
PKCS#7 格式。由于 .p7b 文件已经包含完整的证书链,一条命令即可将所有内容一次性导入到您现有的私钥别名中:
keytool -import -trustcacerts -alias ssldragon -keystore example.jks -file example.p7b
将ssldragon替换为您自己的别名,将example替换为您的文件名。该别名必须是已经持有您私钥的那个别名(即 CSR 步骤中使用的别名)。当您看到提示信息Certificate reply was installed in keystore时,说明导入成功。使用以下命令验证 keystore 内容:
keytool -list -v -keystore example.jks
查找类型为PrivateKeyEntry且证书链长度大于 1 的条目。这可以确认已签名的证书现在已附加到您的私钥上。
PEM 格式。请按证书链顺序分别导入各证书:先导入根证书,再导入任何中间证书,最后导入您的域名证书。先导入证书链可以让 keytool 在附加签名回复到您的私钥之前先构建完整的信任路径。导入根证书:
keytool -import -trustcacerts -alias root -keystore example.jks -file root.crt
然后导入中间证书:
keytool -import -trustcacerts -alias intermediate -keystore example.jks -file intermediate.crt
如果您的 CA 提供了多个中间证书,请将每一个都导入到各自独立的可信别名下,并按照它们相互签名的顺序进行(从根证书向下依次到您的域名证书)。例如,Sectigo 的 Sectigo PositiveSSL 证书附带不止一个中间证书,因此需要在域名证书之前依次导入它们。
最后,将您的主证书(为您的域名颁发的证书)导入到现有的私钥别名中,即您生成 CSR 时所用的同一个别名:
keytool -import -trustcacerts -alias ssldragon -keystore example.jks -file example.crt
这里,ssldragon必须是您现有的私钥别名。由于该别名已经持有一个密钥,keytool 会将此次导入视为一次证书回复(certificate reply),并将已签名的证书绑定到该密钥上。这一步正是让 HTTPS 正常工作的关键所在。
关键陷阱:不要将已签名的证书导入到一个全新的别名下。如果该别名没有现有的私钥,keytool 会将证书作为一个独立的可信条目存储,而不附带任何密钥,这将导致 TLS 失败。如果您不确定哪个别名持有您的密钥,请运行keytool -list -v -keystore example.jks,并使用类型为PrivateKeyEntry的那个别名。
步骤三:在 server.xml 中配置 HTTPS 连接器
在证书导入 keystore 之后,需要让 Tomcat 的 HTTPS 连接器指向它。连接器定义在server.xml中,该文件位于 Tomcat 安装目录下的conf文件夹中(例如$CATALINA_HOME/conf/server.xml)。请用文本编辑器打开该文件。
在当前的 Tomcat 版本(9、10 和 11)中,推荐的写法是嵌套一个SSLHostConfig元素,该元素内又包含一个引用您 keystore 的Certificate元素。请添加或更新安全连接器,使其如下所示:
<Connector
port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig>
<Certificate
certificateKeystoreFile="/your_path/example.jks"
certificateKeystorePassword="your_keystore_password"
certificateKeystoreType="JKS"
certificateKeyAlias="ssldragon"
type="RSA" />
</SSLHostConfig>
</Connector>
- certificateKeystoreFile:您 keystore 文件的完整路径。
- certificateKeystorePassword:keystore 密码。
- certificateKeystoreType:对于 .jks keystore 为JKS,对于 .p12 / .pfx keystore 为PKCS12。
- certificateKeyAlias:持有您私钥和已签名证书的别名(此处为ssldragon)。这告诉 Tomcat 当 keystore 中包含多个条目时应使用哪一个。
注意:上面使用的端口443是标准的 HTTPS 端口;Tomcat 自带的示例默认使用8443,因此请根据您的环境需求选择合适的端口。如果这是您第一次进行 HTTPS 配置,安全连接器在 server.xml 中可能是被注释掉的。请移除周围的注释标记以激活该连接器,并确保没有其他连接器已经占用了同一端口。
旧式写法(较早版本的 Tomcat)。较旧的指南会将 keystore 相关信息直接以keystoreFile和keystorePass属性放在连接器上。这种写法已被上面展示的SSLHostConfig和Certificate元素取代,在受支持的 Tomcat 版本中应使用后者。
步骤四:保存 server.xml 并重启 Tomcat
保存 server.xml 文件,然后重启 Tomcat 以使配置重新加载。在 Linux 上,可使用自带的脚本:
$CATALINA_HOME/bin/shutdown.sh
$CATALINA_HOME/bin/startup.sh
如果 Tomcat 是以服务方式运行的,请改用您的服务管理器进行重启(例如在 Linux 上使用systemctl restart tomcat,或在 Windows 上使用服务面板)。恭喜,您的 SSL 证书现已成功安装在 Tomcat 服务器上。
测试您的 Tomcat SSL 安装
安装证书后,一些微小的错误可能在不知不觉中出现,并影响浏览器对您网站的处理方式。养成检查安装情况的习惯。运行我们的 SSL 检测工具(SSL Checker)进行即时扫描,可以发现诸如缺少中间证书或信任链不完整等问题。
常见问题
通常的原因是将已签名的证书导入到了一个新的别名下,而不是已经持有您私钥的那个别名。这样一来,keytool 会将其存储为一个没有密钥的可信证书条目,导致 Tomcat 无法完成 TLS 握手。请将已签名的回复重新导入到现有的私钥别名(即您 CSR 中使用的那个别名)。可以通过运行keytool -list -v -keystore example.jks并检查该别名是否显示为PrivateKeyEntry且证书链长度大于 1,来确认是否成功。
应先导入证书链。按顺序将根证书和任何中间证书作为可信条目添加,然后最后将您的域名证书导入到私钥别名中。这样可以让 keytool 在将回复附加到您的密钥之前先构建完整的信任路径。如果是 PKCS#7(.p7b)文件,证书链已经打包在一起,因此一次导入即可完成所有操作。
HTTPS 连接器定义在server.xml中,位于 Tomcat 安装目录下的conf文件夹中(例如$CATALINA_HOME/conf/server.xml)。在当前的 Tomcat 版本中,keystore 是通过一个嵌套的SSLHostConfig和Certificate元素进行引用的,而不是直接在连接器上设置。
可以。Tomcat 同时支持两种格式。对于 .p12 或 .pfx keystore,将certificateKeystoreType设置为PKCS12;对于 .jks keystore,则设置为JKS,并将certificateKeystoreFile指向相应的文件。PKCS12 是标准的、可移植的 keystore 格式,因此对于新建的 keystore 来说是不错的默认选择。
Tomcat 的示例配置中,安全连接器使用的是8443端口。若要在浏览器默认使用的标准端口上提供 HTTPS 服务,请将连接器的port设置为443,并确保没有其他连接器或服务已经占用该端口。
运行自带脚本$CATALINA_HOME/bin/shutdown.sh,然后运行$CATALINA_HOME/bin/startup.sh;或者通过您的服务管理器重启 Tomcat 服务(例如在 Linux 上使用systemctl restart tomcat,或在 Windows 上使用服务面板)。必须重启后,对 server.xml 所做的更改才能生效。


