用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);
}
}
};
}
}
发起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;
}
这里发送的是同步请求,得想办法把它变成异步的,同时结合上一些消息队列的技术
本文介绍了如何使用openssl创建自签名证书,并在SpringBoot应用中配置HTTPS,确保与HTTP请求兼容。详细讨论了SpringBoot不同版本的配置差异,包括yml与properties配置,以及端口冲突的解决。在实现HTTPS请求时,指出了可能出现的错误,如证书路径问题和Subject Alternative Names不匹配,并给出了相应解决方案。最后,提到了将HTTPS请求转换为异步请求和结合消息队列技术的可能性。
2074

被折叠的 条评论
为什么被折叠?



