0.环境
本文的相关源码位于 https://github.com/dreamingodd/CA-generation-demo
必须安装nginx,必须安装openssl,(用apt-get update, apt-get install来安装比较简单)
1.配置和脚本
先创建一个demo目录(位置自己选择,我选择建在nginx的目录下):
mkdir /etc/nginx/ca-demo
cd /etc/nginx/ca-demo
修改SSL配置openssl.cnf(也可能是openssl.conf,不知道在哪可以用find -name / openssl.cnf查找)
将dir属性改成你上一步自建的目录,不要用相对路径,会踩坑,保存,如图:
我喜欢自动化,所以写了三个如下脚本,可以直接使用:
ca.sh:
#!/bin/bash #Create directory hierarchy.创建目录结构
touch index.txt serial
chmod index.txt serial
echo > serial
mkdir -p newcerts private
#生成RSA密钥对
openssl genrsa -des3 -out ./private/cakey.pem
#openssl req -new -days -key ./private/cakey.pem -out ca.csr
#openssl ca -selfsign -in ca.csr -out ca.crt
# one step.一步生成csr,crt,直接10年使用期
openssl req -new -x509 -days -key ./private/cakey.pem -out ca.crt
server.sh:
#!/bin/bash
# 签发服务器证书
mkdir server
openssl genrsa -out ./server/server.key
openssl req -new -key ./server/server.key -out ./server/server.csr
openssl ca -in ./server/server.csr -cert ./ca.crt -keyfile ./private/cakey.pem -out ./server/server.crt -days
client.sh:
#!/bin/bash
# 签发client证书
mkdir client
openssl genrsa -des3 -out ./client/client.key
openssl req -new -key ./client/client.key -out ./client/client.csr
openssl ca -in ./client/client.csr -cert ./ca.crt -keyfile ./private/cakey.pem -out ./client/client.crt -config "/etc/ssl/openssl.cnf"
openssl pkcs12 -export -clcerts -in ./client/client.crt -inkey ./client/client.key -out ./client/client.p12
以上三个脚本都可以在 https://github.com/dreamingodd/CA-generation-demo 找到
将以上三个脚本复制到自建demo目录中,如下所示:
加入运行权限:
chmod +x *.sh
结果如下:
2.自建CA证书
运行脚本ca.sh,效果如下:
a.输入密码短语:(随便,记住就行,我填的是"demo",需要填3次)
b.生成证书需要填入一些信息:Country Name(国家),State or Province Name(省),Locality Name(市),Organizational Name(组织名,随便填,我填的是Choosefine Ltd),Common Name(一般填域名),其他可以不填。
这样证书就生成并自签名了:
其中,newcerts目录用于存放CA签署(颁发)过的数字证书(证书备份目录)。private目录用于存放CA的私钥。 文件serial和index.txt分别用于存放下一个证书的序列号和证书信息数据库。 文件serial填写第一个证书序列号(如10000001),之后每前一张证书,序列号自动加1。
可以把ca.crt下载到你的windows系统的PC机上,后面会用到。
3.签发服务端证书
运行脚本server.sh,效果如下:
最后一句是Data Base Updated,就表示成功了,要填的东西跟上一步非常相似,需要注意的是:
a.国家和省份必须和上一步一样。
b.Organizational Name必须和上一步一样。
c.Common Name,如果你的测试服务器有域名的话,填入域名,没有的话随便填一个网址,windows访问测试时配置一下hosts就好,我这里填的是ssl.demo.com。
d.challenge password随便填,记住就行,我填的demo。
e.pass phrase密码短语是CA证书的的,我生成的时候用的也是demo。
生成结果:
4.Nginx配置Https单向认证
这一步我要使用上面我们生成的证书s来配置一个安全的Https单向访问资源链接。
首先修改nginx配置文件,
vi /etc/nginx/nginx.conf
在http中加入以下内容:
server {
server_name ssl.demo.com;
listen ;
ssl on;
ssl_certificate ca-demo/server/server.crt;
ssl_certificate_key ca-demo/server/server.key;
location / {
root html;
index index.html index.htm;
}
}
运行以下命令检查和重启nginx:
/usr/sbin/nginx -t
service nginx restart
使用IP访问一下:
成功了,会显示证书不安全。一般来说,如果花钱使用证书公司签发的server.crt和server.key不会有这个问题。
这里想解决这个问题的话需要windows本地信任我们自己的CA证书。如果对这个问题不感兴趣可以直接跳过。
首先,将我们第二步生成的CA证书下载到windows系统本地,双击打开
点击安装:
点击下一步:
选择自定义证书集合,点击浏览:
选择第二个,受信任的证书列表,一直下一步/完成/是的等,就可以了。
成功后效果如图:
一开始那个X已经没有了。
Status显示OK。
如果你想看到证书集合的情况,可以WIN+R -> certmgr.msc查看
名字是CA证书的Common Name。
最后(如果没有域名),修改以下hosts文件模拟一下域名:
使用域名访问,风险提示就消失了:
5.签发客户端证书
签发客户端证书,用于服务端开启了ssl的客户端验证时,要求客户端对请求做加密。
运行脚本client.sh
所有密码处我填的全是demo。
结果如下:
到此为止,证书的生成已经全部讲完了。
6.Nginx配置Https双向认证
Https双向认证不仅验证服务端的证书,服务端也要验证客户端的证书;不仅对客户端的请求进行了加密,并且服务端使用的加密方案也是使用客户端公钥加密后发送给客户端的。比单项认证更加安全。
我个人的理解是,单项认证防止请求被篡改,双向认证防止请求被模拟。
题外话,Https使用了对称加密+非对称加密,由于非对称加密的效率低,不适合传输的数据量大的时候。所以Https的客户端将对称加密的密钥用服务端的公钥进行加密再发送给服务端,服务端用私钥进行解密(非对称加密),对传输数据本身的加密使用的密钥是一样的(对称加密)。
进入正题,首先开启服务端nginx的客户端ssl认证,将之前加入的配置删除,贴入新的一份:
server {
server_name ssl.demo.com;
listen ;
ssl on;
ssl_certificate ca-demo/server/server.crt;
ssl_certificate_key ca-demo/server/server.key; ssl_client_certificate ca-demo/ca.crt;
ssl_verify_client on; ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on; location / {
root html;
index index.html index.htm;
}
}
检查并重启,再次访问:
显示未发送客户端证书。
下载client.p12文件到本地,双击安装,这次安装到个人:
关闭浏览器再次访问,就有了证书选择的界面,选择后正常访问。
之前有不少网银都是使用这种方式进行交易的。
7.使用Java访问双向认证的Https资源
下一篇再讲...
未完待续...
To be Continued...
下一篇在这儿:http://www.cnblogs.com/dreamingodd/p/7491098.html
本文的相关源码位于 https://github.com/dreamingodd/CA-generation-demo
dreamingodd原创文章,如转载请注明出处。