springboot实现https双向认证
1.生成证书
#生成服务端密钥文件xdd-server.jks keytool -genkey -alias xdd-server -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore xdd-server.jks -dname CN=pero,OU=pero,O=pero,L=sz,ST=gd,C=cn -validity 3650 -storepass xxx-password-xxx -keypass xxx-password-xxx #导出服务端的xdd-server.cer文件 keytool -export -alias xdd-server -file xdd-server.cer -keystore xdd-server.jks -storepass xxx-password-xxx #生成客户端的密钥文件xdd-client.jks keytool -genkey -alias xdd-client -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore xdd-client.jks -dname CN=pero,OU=pero,O=pero,L=sz,ST=gd,C=cn -validity 3650 -storepass xxx-password-xxx -keypass xxx-password-xxx #导出客户端的xdd-client.cer文件 keytool -export -alias xdd-client -file xdd-client.cer -keystore xdd-client.jks -storepass xxx-password-xxx #把客户端的xdd-client.cer导入到服务端 keytool -import -alias xdd-client -file xdd-client.cer -keystore xdd-server.jks -storepass xxx-password-xxx #把服务端的xdd-server.cer导入到客户端 keytool -import -alias xdd-server -file xdd-server.cer -keystore xdd-client.jks -storepass xxx-password-xxx #检验服务端是否具有自己的private key和客户端的cert keytool -list -keystore xdd-server.jks -storepass xxx-password-xxx #转换JKS格式为P12 keytool -importkeystore -srckeystore xdd-client.jks -destkeystore xdd-client.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass xxx-password-xxx -deststorepass xxx-password-xxx -srckeypass xxx-password-xxx -destkeypass xxx-password-xxx -srcalias xdd-client -destalias xdd-client -noprompt
2.springboot服务端配置
server.ssl.enabled=true server.ssl.key-store-type=JKS server.ssl.key-store=classpath:xdd-server.jks server.ssl.key-store-password=xxx-password-xxx server.ssl.key-password=xxx-password-xxx server.ssl.key-alias=xdd-server server.ssl.trust-store=classpath:xdd-server.jks server.ssl.trust-store-password=xxx-password-xxx server.ssl.trust-store-provider=SUN server.ssl.trust-store-type=JKS server.ssl.client-auth=need
3.chrome浏览器配置
配置完证书,重新访问即可
4.postman/apipost配置
5.客户端访问https服务
springboot服务的客户端配置RestTemplate即可
以下为httpclient的实现
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
/** * @ClassName: * @Description: * @author: wdgde * @date: 2024/4/28 11:48 */ public class HttpsClientTest { public static void main(String ...args) throws Exception { final String certFile = "C:\\xxx\\xxxxx\\xdd-client.p12"; final String storePass = "xxx-password-xxx"; final String keyPass = "xxx-password-xxx"; KeyStore keyStore; try (FileInputStream fis = new FileInputStream(certFile)) { keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(fis, storePass.toCharArray()); } SSLContextBuilder sslContextBuilder = SSLContexts.custom(); //TrustStrategy: 一个接口 //TrustAllStrategy: 信任所有 //TrustSelfSignedStrategy: 信任自签名证书 sslContextBuilder.loadTrustMaterial(TrustAllStrategy.INSTANCE); sslContextBuilder.loadKeyMaterial(keyStore, keyPass.toCharArray()); SSLContext sslContext = sslContextBuilder.build(); HttpClientBuilder httpClientBuilder = HttpClients.custom(); httpClientBuilder.setSSLContext(sslContext); //忽略证书里面的 host 和 实际请求的 host 不一致验证 httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE); CloseableHttpClient httpClient = httpClientBuilder.build(); // 创建HttpGet实例,设置需要访问的URL HttpGet httpGet = new HttpGet("https://localhost:8080/pero/xdd"); // 执行GET请求 HttpResponse response = httpClient.execute(httpGet); // 获取响应实体 String responseBody = EntityUtils.toString(response.getEntity()); // 打印响应内容 System.out.println(responseBody); } }
6.curl命令使用证书访问
#生成pem文件,需要输入密码 openssl pkcs12 -in xdd-client.p12 -out xdd-client.pem #访问 curl -k --cert xdd-client.pem:xxx-password-xxx https://localhost:8080/pero/xdd
7.其他
keytool 用法: -certreq [-v] [-protected] [-alias <别名>] [-sigalg ] [-file ] [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -changealias [-v] [-protected] -alias <别名> -destalias <目标别名> [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -delete [-v] [-protected] -alias <别名> [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -exportcert [-v] [-rfc] [-protected] [-alias <别名>] [-file <认证文件>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -genkeypair [-v] [-protected] [-alias <别名>] [-keyalg ] [-keysize <密钥大小>] [-sigalg ] [-dname ] [-validity ] [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -genseckey [-v] [-protected] [-alias <别名>] [-keypass <密钥库口令>] [-keyalg ] [-keysize <密钥大小>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -importcert [-v] [-noprompt] [-trustcacerts] [-protected] [-alias <别名>] [-file <认证文件>] [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -importkeystore [-v] [-srckeystore <源密钥库>] [-destkeystore <目标密钥库>] [-srcstoretype <源存储类型>] [-deststoretype <目标存储类型>] [-srcstorepass <源存储库口令>] [-deststorepass <目标存储库口令>] [-srcprotected] [-destprotected] [-srcprovidername <源提供方名称>] [-destprovidername <目标提供方名称>] [-srcalias <源别名> [-destalias <目标别名>] [-srckeypass <源密钥库口令>] [-destkeypass <目标密钥库口令>]] [-noprompt] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -keypasswd [-v] [-alias <别名>] [-keypass <旧密钥库口令>] [-new <新密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -list [-v | -rfc] [-protected] [-alias <别名>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -printcert [-v] [-file <认证文件>] -storepasswd [-v] [-new <新存储库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>]
参考链接:
https://blog.csdn.net/YYBDESHIJIE/article/details/109261837
http://www.cdiso.cn/article/cheeed.html
https://blog.csdn.net/joelcat/article/details/116004885
https://cloud.tencent.com/developer/article/1853406