curl https
基本流程
①客户端的浏览器向服务器传送客户端 SSL 协议的版本号,加密算法的种类,产生的随机数,
以及其他服务器和客户端之间通讯所需要的各种信息。
②服务器向客户端传送 SSL 协议的版本号,加密算法的种类,随机数以及其他相关信息,
同时服务器还将向客户端传送自己的证书。
③客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:
证书是否过期,
发行服务器证书的 CA 是否可靠,
发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,
服务器证书上的域名是否和服务器的实际域名相匹配。
如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。
④用户端随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)
对其加密,然后将加密后的“预主密码”传给服务器。
⑤如果服务器要求客户的身份认证(在握手过程中为可选),用户可以建立一个随机数然后对其进行数据签名,
将这个含有签名的随机数和客户自己的证书以及加密过的“预主密码”一起传给服务器。
⑥如果服务器要求客户的身份认证,服务器必须检验客户证书和签名随机数的合法性,
具体的合法性验证过程包括:
客户的证书使用日期是否有效,
为客户提供证书的CA 是否可靠,
发行CA 的公钥能否正确解开客户证书的发行 CA 的数字签名,
检查客户的证书是否在证书废止列表(CRL)中。
检验如果没有通过,通讯立刻中断;如果验证通过,服务器将用自己的私钥解开加密的“预主密码”,
然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。
⑦服务器和客户端用相同的主密码即“通话密码”,一个对称密钥用于 SSL 协议的安全数据通讯的加解密通讯。
同时在 SSL 通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。
⑧客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。
⑨服务器向客户端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。
⑩SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。
单向认证模式与双向认证模式的区别,就在于第⑤、第⑥步是否要求对客户的身份认证。单向不需要认证,双向需要认证。
使用curl来访问双向认证的https站点
一、准备工作
1
首先,因为要进行客户端认证,你应该具有了客户端的个人证书(对于公司内网,通常是由IT的管理员颁发给你的),
只要你能够顺利的访问双向认证的https站点,你就具有了个人证书,它藏在浏览器上。我们要做的工作,只是把它从浏览器中导出来。
从IE浏览器导出来的格式,通常为.pfx格式,从firefox导出来的格式通常为.p12格式,
其实pfx=p12,它们是同一个东西,对于curl而言这种格式称为PKCS#12文件。
2
把p12格式转换为pem格式(假设你的p12文件名为:xxx.p12):
openssl pkcs12 -in xxx.p12 -out client.pem -nokeys #客户端个人证书的公钥
openssl pkcs12 -in xxx.p12 -out key.pem -nocerts -nodes #客户端个人证书的私钥
也可以转换为公钥与私钥合二为一的文件;
openssl pkcs12 -in xxx.p12 -out all.pem -nodes #客户端公钥与私钥,一起存在all.pem中
在执行过程中,可能需要你输入导出证书时设置的密码。执行成功后,我们就有了这些文件:client.pem——客户端公钥,key.pem——客户端私钥,或者二合一的all.pem。
3
确保你安装的curl版本正确(本人折腾了两天,全因为fedora13下的curl-7.20.1有问题,更新到curl-7.21.0.tar.gz问题解决)。
二、执行curl命令
1
使用client.pem+key.pem
curl -k --cert client.pem --key key.pem https://www.xxxx.com
2
使用all.pem
curl -k --cert all.pem https://www.xxxx.com
使用-k
,是不对服务器的证书进行检查,这样就不必关心服务器证书的导出问题了。
三、访问https
1
curl以GET方式请求https协议接口
//注意:这里的$url已经包含参数了,不带参数你自己处理哦GET很简单
function curl_get_https($url){
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true); // 从证书中检查SSL加密算法是否存在
$tmpInfo = curl_exec($curl); //返回api的json对象
//关闭URL请求
curl_close($curl);
return $tmpInfo; //返回json对象
}
2
curl以POST方式请求https协议接口
/* PHP CURL HTTPS POST */
function curl_post_https($url,$data){ // 模拟提交数据函数
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
$tmpInfo = curl_exec($curl); // 执行操作
if (curl_errno($curl)) {
echo 'Errno'.curl_error($curl);//捕抓异常
}
curl_close($curl); // 关闭CURL会话
return $tmpInfo; // 返回数据,json格式
}
3
私有证书访问https
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch, CURLOPT_SSLCERT,dirname(__FILE__).'/card_test/apiclient_cert.pem'); //client.
curl_setopt($ch, CURLOPT_SSLKEY, dirname(__FILE__).'/card_test/apiclient_key.pem');
Ref
https://blog.csdn.net/x356982611/article/details/80218219