You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot内嵌Tomcat配置GoDaddy SSL证书:p12文件来源疑问

问题描述

接手了一个基于Spring Boot内嵌Tomcat搭建的网站,该网站使用.jks文件实现HTTPS。当前SSL证书已过期,尝试用从GoDaddy获取的文件生成新的.jks文件,但参考文档步骤中未说明website_name_here.p12文件的来源。参考步骤及网站配置代码如下:

参考文档生成.jks的步骤

These are the steps in document to create .jks file:

Security Settings
C:\trash\keyproc>openssl req -new -newkey rsa:2048 -nodes -keyout website_name_here.key -out website_name_here.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:XX
State or Province Name (full name) [Some-State]:XXXXX
Locality Name (eg, city) []:XXXX
Organization Name (eg, company) [Internet Widgits Pty Ltd]:XXXXX
Organizational Unit Name (eg, section) []:Software Development
Common Name (e.g. server FQDN or YOUR name) []:website_name_here.co
Email Address []:xxxxx@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:pwd_here
An optional company name []:xxxxx
Two files are generated website_name_here.key & website_name_here.csr
Use website_name_here.csr generated to get certificate from Godaddy.
Get SSL cetrificate from Godaddy and extract to this folder.

####################  Java Version 17 was active from hereon #################################################################

Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.


C:\trash\keyproc>keytool -importkeystore -deststorepass pwd_here -destkeystore website_name_here.jks -srckeystore website_name_here.p12 -srcstoretype PKCS12
Importing keystore website_name_here.p12 to website_name_here.jks...
Enter source keystore password:
Entry for alias website_name_here.co successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore website_name_here.jks -destkeystore website_name_here.jks -deststoretype pkcs12".

C:\trash\keyproc>

After this just import  main CRT file not bundle file using keytool.

网站HTTPS配置代码

Tomcat自定义配置类

import lombok.SneakyThrows;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.util.Optional;
//@Profile("dev")
@Component
public class TomcatEmbedServerCustomConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>
{
    private static final Logger logger = LoggerFactory.getLogger(TomcatEmbedServerCustomConfiguration.class);

    IWebApplicationServerSettingsRepository appSettinsRepository;

    ApplicationHttpsSettingsEntityRepository applicationHttpsSettingsEntityRepository;

    public TomcatEmbedServerCustomConfiguration(IWebApplicationServerSettingsRepository appSettinsRepository, ApplicationHttpsSettingsEntityRepository applicationHttpsSettingsEntityRepository)
    {
        this.appSettinsRepository = appSettinsRepository;
        this.applicationHttpsSettingsEntityRepository = applicationHttpsSettingsEntityRepository;
    }

    @SneakyThrows
    @Override
    public void customize(TomcatServletWebServerFactory factory)
    {
        logger.info("Setting the Tomcat specific configurations. started");
        try
        {

            Optional<WebApplicationServerSettingEntity> serverSettingEntity = appSettinsRepository.findById(1);

            if (serverSettingEntity.isPresent())
            {
                factory.setPort(serverSettingEntity.get().getPort().getPORT());
                factory.setAddress(InetAddress.getByName(serverSettingEntity.get().getHost()));
            }
            factory.setServerHeader("Server header of tomcat");

// HTTPS Settings - Begin

            Optional<ApplicationHttpsSettingsEntity> applicationHttpsSettingsEntity = applicationHttpsSettingsEntityRepository.findById(1);

            if(applicationHttpsSettingsEntity.isPresent())
            {
                logger.info("Setting HTTPS settings....");
                if(applicationHttpsSettingsEntity.get().getUseHttps() !=0)
                {
                    factory.addAdditionalTomcatConnectors(createSslConnector());
                    factory.addContextCustomizers(context ->
                                                  {
                                                      logger.info("Setting HTTPS settings....setting...");
                                                      SecurityConstraint securityConstraint = new SecurityConstraint();
                                                      securityConstraint.setUserConstraint("CONFIDENTIAL");
                                                      SecurityCollection collection = new SecurityCollection();
                                                      collection.addPattern("/*");
                                                      securityConstraint.addCollection(collection);
                                                      context.addConstraint(securityConstraint);
                                                      logger.info("Setting HTTPS settings....setting...Done");
                                                  });
                }
                logger.info("Setting HTTPS settings....End");
            }
// HTTPS Settings - end
            logger.info("Tomcat Server Configuration Host=[" + factory.getAddress() + "] Port=[" + factory.getPort() + "]");
            logger.info("Setting the Tomcat specific configurations. ended");
        }
        catch (Exception e)
        {
            logger.error(e.getMessage());
            throw e;
        }
    }

// HTTPS Settings - Begin
    private Connector createSslConnector() {


        Optional<ApplicationHttpsSettingsEntity> applicationHttpsSettingsEntity = applicationHttpsSettingsEntityRepository.findById(1);

        if(applicationHttpsSettingsEntity.isPresent())
        {
            logger.info("Creating SSL Connector...");

            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
            //            File keystore = new ClassPathResource("website_name.jks").getFile();
//            File truststore = new ClassPathResource("keystore").getFile();
            connector.setScheme("https");
            connector.setSecure(applicationHttpsSettingsEntity.get().getUseHttps() != 0);
            connector.setPort(applicationHttpsSettingsEntity.get().getBroadcaster().getPORT());
            protocol.setSSLEnabled(applicationHttpsSettingsEntity.get().getUseHttps() != 0);
//            protocol.setKeystoreFile("file:///c://trash//website_name_here.jks");
            protocol.setKeystoreFile(applicationHttpsSettingsEntity.get().getKeyStore());
//            protocol.setKeystorePass("pwd_here");
            protocol.setKeystorePass(applicationHttpsSettingsEntity.get().getKeyStorePassword());
//            protocol.setTruststoreFile(truststore.getAbsolutePath());
//            protocol.setTruststorePass("changeit");
            protocol.setKeyAlias(applicationHttpsSettingsEntity.get().getKeyAlias());
            logger.info("Creating SSL Connector...Done");
            return connector;
        }

        return null;
    }
// HTTPS Settings - End
}

Security配置类

@Configuration
//@Profile("production")
public class SecurityConfig
{
// HTTPS Settings - Begin
    @Bean
    public TomcatServletWebServerFactory httpsRedirectConfig()
    {
        return new TomcatServletWebServerFactory()
        {
            @Override
            protected void postProcessContext(Context context)
            {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
    }
// HTTPS Settings - End
}

请问website_name_here.p12文件应从何处获取?


解决方案

website_name_here.p12并不是直接从GoDaddy获取的文件,而是需要你自行用GoDaddy颁发的SSL证书文件和**之前生成的私钥文件(website_name_here.key)**通过OpenSSL命令生成的PKCS12格式密钥库。具体步骤如下:

1. 确认GoDaddy下载的证书文件

从GoDaddy获取SSL证书后,通常会得到两类文件:

  • 网站主证书(例如website_name_here.crt)
  • 中间证书(例如gd_bundle-g2-g1.crt)

2. 合并证书链(推荐)

为保证浏览器兼容性,先将主证书和中间证书合并成完整的证书链文件:

type website_name_here.crt gd_bundle-g2-g1.crt > full_chain.crt

3. 生成.p12文件

使用OpenSSL将私钥和合并后的证书链打包成PKCS12格式文件:

openssl pkcs12 -export -in full_chain.crt -inkey website_name_here.key -out website_name_here.p12 -name website_name_here.co

执行命令时需设置源密钥库密码,该密码要与后续keytool命令中使用的密码一致(即参考文档里的pwd_here)。

4. 继续生成.jks文件

拿到website_name_here.p12后,即可执行参考文档中的keytool命令,将其转换为JKS格式:

keytool -importkeystore -deststorepass pwd_here -destkeystore website_name_here.jks -srckeystore website_name_here.p12 -srcstoretype PKCS12

额外说明

  • 若不想合并证书,也可直接使用主证书生成.p12,但完整证书链能避免部分浏览器出现证书信任问题。
  • 生成.p12时的-name参数需与JKS中的密钥别名一致(对应配置类里的keyAlias),即文档中的website_name_here.co。

内容的提问来源于stack exchange,提问作者Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:45:48