介绍了SSL双向认证的一些基本问题,以及使用Nginx+PHP基于它搭建https的Webservice。

之前的方式只是实现1:1的模式,昨天同事继续实现了n:1的模式,这里我再整理记录下。

由于nginx的ssl_client_certificate参数只能指定一个客户端公钥,如果增加一个客户端进行通信就要重新配一个server。

n:1的模式是通过CA的级联证书模式实现的,首先自己生成一套CA根级证书,再借助其生成二级证书作为client证书。

此时client私钥签名不仅可以通过对应的client公钥验证,还可通过根证书的公钥进行验证。

看到这里应该豁然开朗了吧,下面简单介绍下具体怎么操作:

1 准备工作

1.1 openssl目录准备

一般情况下openssl的配置文件都在这个目录/etc/pki/tls,so:

mkdir /etc/pki/ca_linvo

cd /etc/pki/ca_linvo

mkdir root server client newcerts

echo 01 > serial

echo 01 > crlnumber

touch index.txt

1.2 openssl配置准备

修改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

保存退出

2 创建CA根级证书

生成key:openssl genrsa -out /etc/pki/ca_linvo/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工具貌似对它有要求。

3 创建server证书

生成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

说明:

1、这里生成的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

2、-days 参数可根据需要设置证书的有效期,例如默认365天

4 创建client证书

生成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

说明:

1、这里就必须使用级联证书,并且可以重复该步骤,创建多套client证书

2、生成crt时可能会遇到如下报错:

openssl TXT_DB error number 2 failed to update database

参照这里进行操作。

我使用的是方法一,即将index.txt.attr中unique_subject = no

5 配置nginx

这里只列出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

6 测试

6.1 浏览器测试

由于是双向认证,直接通过浏览器访问https地址是被告知400 Bad Request(No required SSL certificate was sent)的,需要在本机安装client证书。
windows上安装的证书需要pfx格式,也叫p12格式,生成方式如下:
openssl pkcs12 -export -inkey
/etc/pki/ca_linvo/client/client.key -in
/etc/pki/ca_linvo/client/client.crt -out
/etc/pki/ca_linvo/client/client.pfx
然后考到windows中双击即可进行安装,安装时会提示输入生成证书时设置的密码。
安装成功后,重启浏览器输入网址访问,浏览器可能会提示你选择证书,选择刚才安装的那个证书即可。
此时有些浏览器会提示用户该证书不受信任,地址不安全之类,这是因为我们的server证书是我们自己颁发的,而非真正的权威CA机构颁布(通常很贵哦~),忽略它既可。

6.2 php curl测试

这里只列出关键的需要设置的curl参数:
  1. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书,不是CA机构颁布的也没关系
  2. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名,如果不想验证也可设为0
  3. curl_setopt($ch, CURLOPT_VERBOSE, '1'); //debug模式,方便出错调试
  4. curl_setopt($ch, CURLOPT_SSLCERT, CLIENT_CRT); //client.crt文件路径,这里我用常量代替
  5. curl_setopt($ch, CURLOPT_SSLCERTPASSWD, CRT_PWD); //client证书密码
  6. curl_setopt($ch, CURLOPT_SSLKEY, CLIENT_KEY); //client.key文件路径

如果出现白板页没有返回信息,一般是证书或密码没有设置正确的问题,请检查。

6.3 php soap测试

首先需要构建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进行调用,构造函数需要设置第二个参数:

  1. $header = array(
  2. 'local_cert' => CLIENT_PEM, //client.pem文件路径
  3. 'passphrase' => CRT_PWD //client证书密码
  4. );
  5. $client = new SoapClient(FILE_WSDL, $header); //FILE_WSDL为要访问的https地址

上一篇博客里最后说到local_cert设置成远程路径的话会报错,好像是因为第一次获取wsdl时并没有使用client证书的原因,需要将wsdl保持成本地文件进行调用;

但是这次测试却没问题,不用另存为本地文件,直接远程获取即可。

本来认为是之前的证书有问题,但是使用之前的那套证书依然可以,很是诡异~~~~~

SSL双向认证(高清版)的更多相关文章

  1. Nginx、SSL双向认证、PHP、SOAP、Webservice、https

    本文是1:1模式,N:1模式请参见新的一篇博客<SSL双向认证(高清版)> ----------------------------------------------------- 我是 ...

  2. PHP基础在线视频教程高清版

    这个是我给大家介绍的PHP基础在线视频教程高清版,目前PHP慢慢垄断WEB的语言编写市场了,PHP 是一种服务器内置式的script 语言,它的出现使得在unix上快速地开发动态web成为现实.PHP ...

  3. apache用户认证,ssl双向认证配置

    安装环境: OS:contos 6.4 httpd:httpd-2.2.15-59.el6.centos.i686.rpm openssl:openssl-1.0.1e-57.el6.i686.rpm ...

  4. SSL双向认证和SSL单向认证的流程和区别

    refs: SSL双向认证和SSL单向认证的区别https://www.jianshu.com/p/fb5fe0165ef2 图解 https 单向认证和双向认证!https://cloud.tenc ...

  5. php实现https(tls/ssl)双向认证

    php实现https(tls/ssl)双向认证 通常情况下,在部署https的时候,是基于ssl单向认证的,也就是说只要客户端认证服务器,而服务器不需要认证客户端. 但在一些安全性较高的场景,如银行, ...

  6. 什么是SSL双向认证,与单向认证证书有什么区别?

    SSL/TLS证书是用于用户浏览器和网站服务器之间的数据传输加密,实现互联网传输安全保护,大多数情况下指的是服务器证书.服务器证书是用于向浏览器客户端验证服务器,这种是属于单向认证的SSL证书.但是, ...

  7. tomcat配置SSL双向认证

    一.SSL简单介绍 SSL(Secure Sockets Layer 安全套接层)就是一种协议(规范),用于保障客户端和服务器端通信的安全,以免通信时传输的信息被窃取或者修改. 怎样保障数据传输安全? ...

  8. SSL双向认证java实现(转)

    本文通过模拟场景,介绍SSL双向认证的java实现 默认的情况下,我认为读者已经对SSL原理有一定的了解,所以文章中对SSL的原理,不做详细的介绍. 如果有这个需要,那么通过GOOGLE,可以搜索到很 ...

  9. 电脑报2014年第43期 pdf高清版

    电脑报2014年第43期 pdf高清版

随机推荐

  1. 用Objective-C的foundation框架解决表达式求值问题

    主要思想: 本程序分2个类 一个是ExpressionString类,主要用于存储表达式以及对它进行求值.以下是该类中的内容: (NSString *)expString//用于存储要计算的表达式: ...

  2. Blu-Ray BRRip 和 BDRip 的区别

    Blu-Ray BRRip & BDRip 的区别 最近看电影有点多,常常看到blueray或者BDRip的格式,所以找了一下这两种格式的区别. BRRip = 来自蓝光盘片的xvid编码 B ...

  3. java oop

    /** 多层嵌套内部类, 调用时要层层往下调用 格式: 外部类.内部类1.内部类2 对象名 = new 外部类().new 内部类1().new 内部类2(); 对象名.属性/方法名(); */ cl ...

  4. MVC控制器给View返回实体

    前言 这几天把vs12更新到了vs12 5了,因为发现我之前装的12有问题,没有mvc,之后就从itellyou上下载了12的update5更新了一下.说实话,从开发到现在,自己只是平时自己玩用mvc ...

  5. HTML5小时钟

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  6. 在Windowx下创建以点开头的.hatccess文件

    转自:在Windowx下创建以点开头的.hatccess文件 Windows有些目录名是不能创建的,有一些文件按照常规方式也是不能创建的,如在Windows下创建文件夹名为con的目录就不行,在win ...

  7. Unity3d Shader开发(一)Properties

    着色器可以定义一个参数列表,可以由开发者在材质检视面板编辑参数.着色器文件中的Properties块定义了这些参数: 语法: Properties { Property [Property ...] ...

  8. 制作第一个UI字体

    为什么要制作UI字体 一般来说,会有系统默认字体共我们使用,但是出于以下两个原因我们经常会需要制作独特的字体. 1.系统字体的风格和美观程度等无法满足需求. 一般来说,系统字体都比较死板.生硬,风格单 ...

  9. 批处理:遍历输出指定后缀格式的文件名.bat

    批处理:遍历输出指定后缀格式的文件名.bat @echo off type nul >C:\result.txt for /r "d:\我的文档\桌面\交接\webservice\We ...

  10. Unity3d与android通信

    原地址:http://www.cnblogs.com/alongu3d/p/3661077.html unity3d与android的通信,从网上搜索了一些文章,发现我的始终不成功!后来调试通了,现在 ...