生成证书
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有可能会把证书文件做编码处理,加上这个可以避免