openssl创建自认证证书后,添加在springboot配置中,从而发起https请求,要求http和https请求兼容

本文介绍了如何使用openssl创建自签名证书,并在SpringBoot应用中配置HTTPS,确保与HTTP请求兼容。详细讨论了SpringBoot不同版本的配置差异,包括yml与properties配置,以及端口冲突的解决。在实现HTTPS请求时,指出了可能出现的错误,如证书路径问题和Subject Alternative Names不匹配,并给出了相应解决方案。最后,提到了将HTTPS请求转换为异步请求和结合消息队列技术的可能性。
部署运行你感兴趣的模型镜像

用openssl创建自认证证书

我是按照这个博客来创建的自认证证书
openssl自认证证书创建
通过openssl指令来生成证书

#生成秘钥
openssl genrsa -out private.key 2048

#生成用于申请请求的证书文件csr,一般会将该文件发送给CA机构进行认证,本例使用自签名证书
openssl req -new -key private.key -out request.csr

#自签名证书
openssl x509 -req -days 365 -in request.csr -signkey private.key -out root.crt

#生成p12文件
openssl pkcs12 -export -out cert.p12 -inkey private.key -in root.crt

#生成p12时记录住密码

#p12文件转换为keystore文件
keytool -importkeystore -srckeystore cert.p12 -destkeystore my.keystore -deststoretype pkcs12

#p12转换为jks
keytool -importkeystore -srckeystore cert.p12 -destkeystore dest.jks -deststoretype pkcs12

#查看证书信息
openssl x509 -noout -text -in root.crt

#从私钥中解析出公钥
openssl rsa -in private.key -pubout -out public.pem

#从JSK文件中提取公钥
keytool -list -rfc -keystore demo.jks -storepass password


将得到的证书保存起来就是公钥
或者通过jdk自带的工具生成证书

${jdkPath}/bin> keytool -genkey -alias client.keystore -keyalg RSA -validity 20000 -keystore xxx.keystore

在springboot的配置文件里添加证书及其他配置信息

此处采用的是yml配置,要求和http兼容

server:
        #https监听端口
        port: 8089
        ssl:
          key-store: classpath:xxx.p12
          key-store-password: #申请证书时自己设置的密码
          key-store-type: PKCS12
          key-alias: #证书别名
          enabled: true
http:
	port: 8081

可能也会用到的properties配置

server.port=8088
server.ssl.key-store=classpath:xxx.p12 #路径在resources底下
server.ssl.key-alias= 
server.ssl.enabled=true
server.ssl.key-store-type= PKCS12
server.ssl.key-store-password= #申请证书时自己设置的密码

这里发生了http和https共同占用一个端口产生的冲突
必须加上字段 enabled: true
必须通过实现一个接口改变容器得端口配置此处还与springboot的版本有关
这个是springboot 1.5.x 版本的配置

package com.woniu.learnhttps.config;
 
import org.apache.catalina.connector.Connector;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 

@Configuration
public class MultiConnectionSupport {
	@Value("${http.port}")
    private int httpPort;
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                if (container instanceof TomcatEmbeddedServletContainerFactory) {
                    TomcatEmbeddedServletContainerFactory containerFactory =
                            (TomcatEmbeddedServletContainerFactory) container;
                    Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
                    connector.setPort(httpPort);
                    containerFactory.addAdditionalTomcatConnectors(connector);
                }
            }
        };
    }
}

这个是springboot 2.x 版本的配置
EmbeddedServletContainerFactory相关类,在springboot 2.x版本中已经被弃用,需要使用WebServerFactoryCustomizer

/**
 * 
 * @function   http访问配置类
 *
 */
@Configuration
public class TomcatConfig {
    
    @Value("${http.port}")
    private int httpPort;

    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer() {
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {

            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                if (factory instanceof TomcatServletWebServerFactory) {
                    TomcatServletWebServerFactory webServerFactory = (TomcatServletWebServerFactory)factory;
                    Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
                    // 设置http访问的端口号,不能与https端口重复,否则会报端口被占用的错误
                    connector.setPort(httpPort);
                    webServerFactory.addAdditionalTomcatConnectors(connector);
                }
            }
        };
    }
      
}

springboot 2.x 配置端口

发起https请求与http请求

通过对比发现,增加了SSLContext的实现,以及证书路径,密码等信息
发送https请求

	/**
	 * 设置信任自签名证书
	 * 	
	 * @param keyStorePath		密钥库路径
	 * @param keyStorepass		密钥库密码
	 * @return
	 */
	public static SSLContext custom(String keyStorePath, String keyStorepass){
		SSLContext sc = null;
		FileInputStream instream = null;
		KeyStore trustStore = null;
		try {
			trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
			instream = new FileInputStream(new File(keyStorePath));
			trustStore.load(instream, keyStorepass.toCharArray());
			// 相信自己的CA和所有自签名的证书
			sc = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
		} catch (KeyStoreException | NoSuchAlgorithmException| CertificateException | IOException | KeyManagementException e) {
			e.printStackTrace();
		} finally {
			try {
				instream.close();
			} catch (IOException e) {
			}
		}
		return sc;
	}

错误分析

  • 证书文件的路径找不到
    使用"src/main/resources/xxx.p12" 找到
  • Certificate for <[url]> doesn’t match any of the subject alternative names: []

全主机可信配置,因为这里cs都是使用的自认证证书,

SSLContext sslcontext = HttpSSLClientUtil.custom("${certPath}", "${pwd}");
SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslcontext,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslcsf).build();               

跳过主机名验证
通过修改证书san解决
包含完整要素的 https post 请求

    public static String doPostJson(String url, String json) {

    	SSLContext sslcontext = HttpSSLClientUtil.custom("${certPath}", "${pwd}");
    	SSLConnectionSocketFactory sslcsf = new SSLConnectionSocketFactory(sslcontext,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    	
    	//设置协议http和https对应的处理socket链接工厂的对象
    	Registry<ConnectionSocketFactory> socketFactoryRegistry 
    	= RegistryBuilder.<ConnectionSocketFactory>create()
          .register("http", PlainConnectionSocketFactory.INSTANCE)
          .register("https", new SSLConnectionSocketFactory(sslcontext))
          .build();
          
        PoolingHttpClientConnectionManager connManager 
        = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        HttpClients.custom().setConnectionManager(connManager);
        
        //创建自定义的httpClient对象
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslcsf).build();
        
        CloseableHttpResponse response=null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

这里发送的是同步请求,得想办法把它变成异步的,同时结合上一些消息队列的技术

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值