Spring Boot单域名下配置多个SSL证书的问题咨询
结论
默认 Spring Boot 配置体系下不支持同时配置两个server.ssl.keyAlias参数,重复声明该配置时,只有最后加载的配置值会生效,旧配置会被直接覆盖。
解决方案按场景区分:
场景1:新旧证书平滑替换(两个证书对应同一个域名)
这种场景完全不需要同时加载两份证书,直接修改配置文件中的server.ssl.keyAlias值为新证书的别名wxyz2即可:
server.port=443 server.ssl.key-store=keystore.p12 server.ssl.key-store-password=myPass server.ssl.keyStoreType=PKCS12 # 替换为新证书别名 server.ssl.keyAlias=wxyz2
旧证书可以暂时保留在密钥库中作为回滚预案,等确认新证书上线运行正常后,再用keytool命令将旧别名wxyz对应的证书从密钥库中删除即可。
场景2:两份证书对应不同域名,需要同时生效(SNI场景)
如果两份证书分别对应不同的域名,需要在同一个服务上同时支持,需要自定义Web服务器的SSL上下文,开启SNI支持,参考配置代码如下:
import org.apache.catalina.connector.Connector; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; @Configuration public class SSLConfig { @Value("${server.ssl.key-store-password}") private String keyStorePassword; @Value("${server.ssl.key-store}") private String keyStorePath; @Value("${server.ssl.keyStoreType}") private String keyStoreType; @Bean public TomcatServletWebServerFactory servletContainer() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.addAdditionalTomcatConnectors(createSslConnector()); return factory; } private Connector createSslConnector() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setPort(443); connector.setSecure(true); connector.setScheme("https"); // 加载密钥库 KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(new ClassPathResource(keyStorePath).getInputStream(), keyStorePassword.toCharArray()); // 开启SSL connector.setAttribute("SSLEnabled", true); SSLHostConfig sslHostConfig = new SSLHostConfig(); // 配置第一份证书 对应wxyz.com域名 SSLHostConfigCertificate cert1 = new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA); cert1.setCertificateKeyAlias("wxyz"); cert1.setCertificateKeystore(keyStore); cert1.setCertificateKeystorePassword(keyStorePassword); sslHostConfig.addCertificate(cert1); // 配置第二份证书 对应第二个域名 SSLHostConfigCertificate cert2 = new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA); cert2.setCertificateKeyAlias("wxyz2"); cert2.setCertificateKeystore(keyStore); cert2.setCertificateKeystorePassword(keyStorePassword); sslHostConfig.addCertificate(cert2); connector.addSslHostConfig(sslHostConfig); return connector; } }
配置完成后启动服务即可自动加载密钥库中两个别名对应的证书,根据请求的域名自动匹配对应的证书返回。
内容的提问来源于stack exchange,提问作者Sobhan
相关产品推荐
相关产品推荐

