生成证书
C="CN"
ST="Zhejiang"
L="HanZhou"
O="Alibaba"
OU="Nginx"
CN="11.22.33.44"
CN_CLIENT="MicroService"
emailAddress="abc@edf.com"
PASSWD="password"
JKS_PASSWD="password"rm -rf temp
mkdir temp
cd temp/
mkdir -p demoCA/newcerts
touch demoCA/index.txt
touch demoCA/serial
echo 01 >> demoCA/serial# 生成自签名根证书 ca key
openssl genrsa -aes128 -passout pass:${PASSWD} -out ca.key 2048
# ca crt(pem) der
openssl req -new -passin pass:${PASSWD} -x509 -key ca.key -out ca.crt -days 3650 -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${emailAddress}"
openssl x509 -in ca.crt -outform DER -out ca.der
openssl x509 -inform der -in ca.der -out ca.pem# server key
# openssl genrsa -aes128 -passout pass:${PASSWD} -out serverKey.pem 2048
openssl genrsa -out serverx.key 2048
# server req
#openssl req -new -passin pass:${PASSWD} -key serverKey.pem -out serverReq.pem -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${emailAddress}"
openssl req -new -key serverx.key -out serverReq.pem -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${emailAddress}"
# server cert
openssl ca -md sha256 -key ${PASSWD} -batch -keyfile ca.key -cert ca.crt -in serverReq.pem -out serverCrt.pem -days 3650
rm serverReq.pem # client key
openssl genrsa -aes128 -passout pass:${PASSWD} -out clientKey.pem 2048
# client req
openssl req -new -passin pass:${PASSWD} -key clientKey.pem -out clientReq.pem -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN_CLIENT}/emailAddress=${emailAddress}"
# client cert
openssl ca -md sha256 -key ${PASSWD} -batch -keyfile ca.key -cert ca.crt -in clientReq.pem -out clientCert.pem -days 3650
rm clientReq.pem # 所有证书,私钥等都可以是 pem, 也可以是 der 格式, 可以转化
# openssl x509 -in ca.crt -outform DER -out ca.der # pem -> der
# openssl x509 -inform der -in ca.der -out ca.pem # der -> pem# 假如要取消某个证书openssl
# openssl ca -keyfile ca.key -cert ca.crt -revoke clientCert.pem# jks
# keyStore for client 客户端会给自己的公钥证书给服务端,服务端判断这个证书是不是自己的信任链上的
openssl pkcs12 -export -out slb_sslclient.p12 -in clientCert.pem -inkey clientKey.pem
keytool -importkeystore -srckeystore slb_sslclient.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore.jks# trustStore for client 服务端给自己的公钥证书给客户端,客户端判断这个证书是不是自己的信用链上的
keytool -import -trustcacerts -file ca.crt -keystore truststore.jks -storepass ${JKS_PASSWD}
nginx配置
# HTTPS server#server {listen 8443 ssl;server_name localhost;ssl_certificate ./nginx/conf/ssl/servercrt.pem;ssl_certificate_key ./nginx/conf/ssl/servercrt.key;ssl_client_certificate ./nginx/conf/ssl/ca.crt;ssl_verify_client on;ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256";ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;ssl_protocols TLSv1.2;location / {# 校验证书DN,防止根证书的其他证书也通过认证if ($ssl_client_s_dn !~ "CN=xxx,OU=xxx,O=xxx,C=CN") {return 403;}proxy_pass https//elasticsearch;} }upstream elasticsearch {server 11.22.33.44:9200;}
java配置
try {String keystorePassPlain = PwdUtils.decryptSecretInfo(keystorePass);KeyStore keyStore = KeyStore.getInstance("jks");kis = new FileInputStream(new File(PathUtil.getAbsolutePath(keystorePath).orElse(StringUtils.EMPTY) + File.separator + "keystore.jks"));keyStore.load(kis, keystorePassPlain.toCharArray());String truststorePassPlain = PwdUtils.decryptSecretInfo(truststorePass);KeyStore trustStore = KeyStore.getInstance("jks");tis = new FileInputStream(new File(PathUtil.getAbsolutePath(keystorePath).orElse(StringUtils.EMPTY) + File.separator + "truststore.jks"));trustStore.load(tis, truststorePassPlain.toCharArray());SSLContextBuilder sslbuild = SSLContexts.custom().loadTrustMaterial(trustStore, (x509Certificates, s) -> {for (X509Certificate x509Certificate : x509Certificates) {x509Certificate.checkValidity();}return false;}).loadKeyMaterial(keyStore, keystorePassPlain.toCharArray()).useProtocol("TLSv1.2");SSLContext sslcontext = sslbuild.build();this.builder.setHttpClientConfigCallback((httpClientBuilder) -> {return httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslcontext);});} catch (Exception var13) {LOG.error("setSSLContext failed.", var13);} finally {try {if (tis != null) {tis.close();}if (kis != null) {kis.close();}} catch (IOException e) {tis = null;kis = null;LOG.error("close fileInputStreams error: ", e);}}
p12证书导入证书到浏览器
根证书,放入 受信任的根证书颁发机构
P12证书包含了客户端私钥和证书,等价于keystore.jks,放入个人
如果使用根证书+中间证书,需要在trustStore中添加整个信用链(包括根证书+中间证书),nginx 上前后复制粘贴放在一个文件里面就行
vi /etc/hosts
Maven有可能会把证书文件做编码处理,加上这个可以避免