概述
通常我们申请的免费SSL证书都用于单向认证,即让客户端能够验证服务器,同时加密HTTP通道。有的时候我们为了安全,需要确保客户端是信任的客户,那如何让服务器也能验证客户端,确保客户端是自己的客户呢,这就需要使用双向认证,让客户端也安装证书。
网上的大多数教程都是通过openssl自己签发证书,具体步骤可以参考:http://www.884358.com/https-auth/
自签的SSL证书不受浏览器认可,地址栏会显示红色的“不安全”字样。
本文介绍如何通过权威机构颁发的免费SSL证书来配置客户端证书。
证书申请
很多大厂都提供了免费SSL证书申请,例如阿里云、腾讯云、Let’s Encrypt等。具体申请过程这里不多介绍。
部署证书
证书申请通过后,点击下载,选择适合自己服务器的证书:
例如我的服务器是Nginx,那么下载Nginx的版本:
下载后解压压缩包,得到两个文件:xxx_www.yourdomian.com.key、xxx_www.yourdomian.com.pem,将这两个文件上传到服务器的任意目录,用于下一步配置。
单向认证配置
单向认证配置只需要在nginx的配置中的server中添加以下代码即可:
server {
listen 443 ssl;
server_name www.yourdomain.com;
#公钥证书
ssl_certificate /data/sslKey/xxx_www.yourdomian.com.pem;
#私钥
ssl_certificate_key /data/sslKey/xxx_www.yourdomian.com.key;
#其他代码省略....
}
配置成功后,地址栏会显示一个锁,且“不安全”字样已消失:
双向认证配置
下载根证书
回到阿里云ssl证书下载页面,下载根证书:
下载后得到Digicert-OV-DV-root.cer
文件,将该文件也上传至上面的证书目录。
配置
双向认证需要在单向认证的基础上,添加如下代码:
# SSL根证书
ssl_client_certificate /data/sslKey/Digicert-OV-DV-root.cer;
# 开启客户端证书验证
ssl_verify_client on;
开启双向认证后,打开浏览器会显示如下界面:
原因为浏览器没有找到对应的客户端证书。
客户端导入证书
回到阿里云证书下载页面,下载Tomcat类型证书:
解压后得到两个文件,一个是证书:xxx_www.yourdomain.com.pfx,一个是证书密码:pfx-password.txt。双击xxx_www.yourdomain.com.pfx文件导入证书,中途需要输入密码,密码在文件pfx-password.txt中。
导入证书后,关闭浏览器,重新打开浏览器,输入网址则会弹出选择证书的页面,点击确定后即可正常访问。
指定目录使用双向验证
有些情况下,我们需要为指定目录(例如后台目录)使用双向验证,其余则使用单向验证。
# SSL根证书
ssl_client_certificate /data/sslKey/Digicert-OV-DV-root.cer;
#开启客户端证书验证
ssl_verify_client optional;
# 指定双向认证客户端证书到根证书的深度,默认是1
ssl_verify_depth 2;
#双向证书验证
location /admin/ {
if ($ssl_client_verify != "SUCCESS") { return 403; }
}
指定目录使用自签ssl证书,其余使用免费ssl证书
由于自签ssl证书会显示红色“不安全”影响用户体验,那么可以让提供给普通用户的网址使用免费ssl证书(单向验证)。指定目录例如后台目录,使用自签ssl证书进行双向验证。
server {
# 监听444端口用于自签SSL证书
listen 444 ssl;
server_name www.yourdomain.com;
ssl_certificate /data/sslKey/server.crt;
ssl_certificate_key /data/sslKey/server.key;
# SSL根证书
ssl_client_certificate /data/sslKey/root.crt;
# 开启客户端证书验证
ssl_verify_client on;
location / {
rewrite ^ https://$host$request_uri? permanent;
}
location /admin {
}
}
server
{
listen 443 ssl;
server_name www.yourdomain.com;
ssl_certificate /data/sslKey/xxx.pem;
ssl_certificate_key /data/sslKey/xxx.key;
#特定目录使用自签SSL进行双向证书验证
location /admin/ {
rewrite ^ https://$host:444$request_uri? permanent;
}
}
感觉不太具有实用价值,这样的话,你证书的私钥都暴露给终端了