最近做一个项目需要用到双向认证,然后研究了下CA证书,以及SSL握手过程,主要是源码相关的。
因为讲理论的文章太多了,讲得也非常好。
refs:
SSL双向认证和SSL单向认证的区别
https://www.jianshu.com/p/fb5fe0165ef2图解 https 单向认证和双向认证!
https://cloud.tencent.com/developer/news/233610SSL/TLS 双向认证(一) -- SSL/TLS工作原理
https://blog.csdn.net/wuliganggang/article/details/78428866SSL 证书格式普及,PEM、CER、JKS、PKCS12
我这里主要讲讲我们在编写springboot web服务有用的信息。
一. 服务器端ssl配置及开启双向认证
如果客户端使用的CA证书,则不需要配置trust-store相关配置
#服务器存放证书的路径,用于服务器收到clientHello消息后,
#回复serverHello并给客户端发送证书时使用
server.ssl.key-store=classpath:config/keystore/server-cert.jks
#证书库密码
server.ssl.key-store-password=abc123
server.ssl.key-alias=1
server.ssl.keyStoreType=JKS
#信任的证书库路径(双向认证的时候,如果客户端是自签名证书,
#需要把客户端证书加到项目中(如下的classpath:keystore/trust-client.jks)
server.ssl.trust-store=classpath:keystore/trust-client.jks
#信任的证书库密码
server.ssl.trust-store-password=abc123
server.ssl.trust-store-type=JKS
server.ssl.trust-store-provider=SUN
#开启客户端证书校验
server.ssl.client-auth=need
二. 客户端(这里指的是使用httpclient访问另一个服务的web服务)ssl相关配置
如果服务器使用的CA证书,则客户端不需要配置上面的trust-store相关配置,
如果服务端使用的自签名证书,则可必须将服务器的证书配置在truest-store中,
并通过SslContext的loadTrustMaterial函数将证书加载到restTemplate并配置信任策略为TrustSelfSignedStrategy。
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
SSLContext sslContext = null;
try {
File trustFile = new File("classpath:config/keystore/server-cert.jks");
File keyFile = new File("classpath:config/keystore/client-cert.jks");
// setup a Trust Strategy that allows all certificates.
sslContext = new SSLContextBuilder()
.loadTrustMaterial(trustFile, "abc123".toCharArray(), TrustAllStrategy.INSTANCE)
.loadKeyMaterial(keyFile, "abc123".toCharArray(), "abc123".toCharArray())
.build();
httpClientBuilder.setSSLContext(sslContext);
} catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
log.info(ExceptionUtils.getStackTrace(e));
} catch (CertificateException | IOException | UnrecoverableKeyException e) {
e.printStackTrace();
}
配置好之后,请打开jvm参数 -Djavax.net.debug=ssl,handshake, 然后你就可以看到所以ssl相关的log输出,log里有完整的握手过程提示,
你可以在任何你需要的地方打断点就行调试。