介绍了SSL双向认证的一些基本问题,以及使用Nginx+PHP基于它搭建https的Webservice。php
以前的方式只是实现1:1的模式,昨天同事继续实现了n:1的模式,这里我再整理记录下。java
因为nginx的ssl_client_certificate参数只能指定一个客户端公钥,若是增长一个客户端进行通讯就要从新配一个server。nginx
n:1的模式是经过CA的级联证书模式实现的,首先本身生成一套CA根级证书,再借助其生成二级证书做为client证书。windows
此时client私钥签名不只能够经过对应的client公钥验证,还可经过根证书的公钥进行验证。浏览器
看到这里应该豁然开朗了吧,下面简单介绍下具体怎么操做:安全
通常状况下openssl的配置文件都在这个目录/etc/pki/tls,so:curl
mkdir /etc/pki/ca_linvo函数
cd /etc/pki/ca_linvo工具
mkdir root server client newcerts
测试
echo 01 > serial
echo 01 > crlnumber
touch index.txt
修改openssl配置
vi /etc/pki/tls/openssl.cnf
找到这句注释掉,替换为下面那句
#default_ca = CA_default
default_ca = CA_linvo
把整个部分拷贝一份,改为上面的名字[ CA_linvo ]
修改里面的以下参数:
dir = /etc/pki/ca_linvo
certificate = $dir/root/ca.crt
private_key = $dir/root/ca.key
保存退出
生成csr:openssl req -new -key /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.csr
生成crt:openssl x509 -req -days 3650 -in /etc/pki/ca_linvo/root/ca.csr -signkey /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.crt
生成crl:openssl ca -gencrl -out /etc/pki/ca_linvo/root/ca.crl -crldays 7
生成的根级证书文件都在/etc/pki/ca_linvo/root/目录下
注意:建立证书时,建议证书密码设置长度>=6位,由于java的keytool工具貌似对它有要求。
生成key:openssl genrsa -out /etc/pki/ca_linvo/server/server.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/server/server.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/server/server.crt -days 3650
说明:
一、这里生成的crt是刚才ca根级证书下的级联证书,其实server证书主要用于配置正常单向的https,因此不使用级联模式也能够:
openssl rsa -in /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.key
openssl x509 -req -in /etc/pki/ca_linvo/server/server.csr -signkey /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.crt -days 3650
二、-days 参数可根据须要设置证书的有效期,例如默认365天
生成key:openssl genrsa -des3 -out /etc/pki/ca_linvo/client/client.key 1024
生成csr:openssl req -new -key /etc/pki/ca_linvo/client/client.key -out /etc/pki/ca_linvo/client/client.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/client/client.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/client/client.crt -days 3650
说明:
一、这里就必须使用级联证书,而且能够重复该步骤,建立多套client证书
二、生成crt时可能会遇到以下报错:
openssl TXT_DB error number 2 failed to update database
可参照这里进行操做。
我使用的是方法一,即将index.txt.attr中unique_subject = no
这里只列出server段的关键部分:
ssl_certificate /etc/pki/ca_linvo/server/server.crt;#server公钥
ssl_certificate_key /etc/pki/ca_linvo/server/server.key;#server私钥
ssl_client_certificate /etc/pki/ca_linvo/root/ca.crt;#根级证书公钥,用于验证各个二级client
ssl_verify_client on;
重启Nginx
首先须要构建client的pem格式证书,经过openssl命令也能够,不过由于咱们已经有了crt和key,因此手动合并也很简单:
新建一个文件,把crt中-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----之间的base64内容(包括这两个分割线)拷贝进去,而后把key中-----BEGIN RSA PRIVATE KEY-----和-----END RSA PRIVATE KEY-----之间的内容也复制进去,而后保存为client.pem便可。
其实更省事的话能够以下命令,直接合并两个文件:
cat /etc/pki/ca_linvo/client/client.crt /etc/pki/ca_linvo/client/client.key > /etc/pki/ca_linvo/client/client.pem
有了pem文件,下面可使用php内置的SoapClient进行调用,构造函数须要设置第二个参数:
上一篇博客里最后说到local_cert设置成远程路径的话会报错,好像是由于第一次获取wsdl时并无使用client证书的缘由,须要将wsdl保持成本地文件进行调用;
可是此次测试却没问题,不用另存为本地文件,直接远程获取便可。
原本认为是以前的证书有问题,可是使用以前的那套证书依然能够,非常诡异~~~~~