CURL使用SSL证书访问HTTPS(错误码60)
2019-03-25 09:07:18 阅读:3083
在支付的交互过程中,安全绝对是需要考虑的重要因素之一。体现在对服务器交互数据的签名等环节,但有的时候为了能达到更高的安全级别,还需要用ssl证书,即web服务器有证书,浏览器客户端/请求端也需要安装证书来达到双向验证。比如请求下面的财付通支付网关,用户向商户账户支付金额,仅仅是需要检查签名就行了https://gw.tenpay.com/gateway/pay.htm但是在退款这一步要请求财付通退款接口时,不仅要验证签名,还要双向验证SSL证书,一旦让自己出钱的时候就变得抠门谨慎了https://mch.tenpay.com/refundapi/gateway/refund.xml这个接口就需要安装在开通服务之后第三方给我们发送的安全证书了。作为文件形式存在的证书一般有这几种格式:1.带有私钥的证书由PublicKeyCryptographyStandards#12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀名。2.二进制编码的证书证书中没有私钥,DER编码二进制格式的证书文件,以cer作为证书文件后缀名。3.Base64编码的证书证书中没有私钥,BASE64编码格式的证书文件,也是以cer作为证书文件后缀名。由定义可以看出,只有pfx格式的数字证书是包含有私钥的,cer格式的数字证书里面只有公钥没有私钥。在pfx证书的导入过程中有一项是“标志此密钥是可导出的。这将您在稍候备份或传输密钥”。一般是不选中的,如果选中,别人就有机会备份你的密钥了。如果是不选中,其实密钥也导入了,只是不能再次被导出。这就保证了密钥的安全。如果导入过程中没有选中这一项,做证书备份时“导出私钥”这一项是灰色的,不能选。只能导出cer格式的公钥。如果导入时选中该项,则在导出时“导出私钥”这一项就是可选的。上图,如果要导出私钥(pfx),是需要输入密码的,这个密码就是对私钥再次加密,这样就保证了私钥的安全,别人即使拿到了你的证书备份(pfx),不知道加密私钥的密码,也是无法导入证书的。相反,如果只是导入导出cer格式的证书,是不会提示你输入密码的。因为公钥一般来说是对外公开的,不用加密由于php的curl只支持pem格式、der、eng格式,而之前生成的是p12的格式,所以需要转换一下PKCS#12到PEM的转换opensslpkcs12-nocerts-nodes-incert.p12-outprivate.pem验证opensslpkcs12-clcerts-nokeys-incert.p12-outcert.pemcurl请求部分代码/**
*使用证书访问退款接口
*
*/
privatestaticfunction_postCert($url)
{
$ch=curl_init($url);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"GET");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,'2');
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,'1');
curl_setopt($ch,CURLOPT_SSLCERT,WECHAT_CERT);
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']);
$response=curl_exec($ch);
return$response;
}参数释义:CURLOPT_TIMEOUT:超时时间CURLOPT_RETURNTRANSFER:是否要求返回数据CURLOPT_SSL_VERIFYPEER:是否检测服务器的证书是否由正规浏览器认证过的授权CA颁发的CURLOPT_SSL_VERIFYHOST:是否检测服务器的域名与证书上的是否一致CURLOPT_SSLCERTTYPE:证书类型,"PEM"(default),"DER",and"ENG".CURLOPT_SSLCERT:证书存放路径CURLOPT_SSLCERTPASSWD:证书密码CURLOPT_SSLKEYTYPE:私钥类型,"PEM"(default),"DER",and"ENG".CURLOPT_SSLKEY:私钥存放路径继续返回false让输出错误显示:PeercertificatecannotbeauthenticatedwithknownCAcertificates说对方的证书不能用已知的CA证书验证其实和使用curl访问一个意思➜Certificatecurl-vhttps://mch.tenpay.com
*RebuiltURLto:https://mch.tenpay.com/
*HostnamewasNOTfoundinDNScache
*Trying183.62.126.37...
*Connectedtomch.tenpay.com(183.62.126.37)port443(#0)
*successfullysetcertificateverifylocations:
*CAfile:none
CApath:/etc/ssl/certs
*SSLv3,TLShandshake,Clienthello(1):
*SSLv3,TLShandshake,Serverhello(2):
*SSLv3,TLShandshake,CERT(11):
*SSLv3,TLSalert,Serverhello(2):
*SSLcertificateproblem:selfsignedcertificateincertificatechain
*Closingconnection0
curl:(60)SSLcertificateproblem:selfsignedcertificateincertificatechain
Moredetailshere:http://curl.haxx.se/docs/sslcerts.html
curlperformsSSLcertificateverificationbydefault,usinga"bundle"
ofCertificateAuthority(CA)publickeys(CAcerts).Ifthedefault
bundlefileisn'tadequate,youcanspecifyanalternatefile
usingthe--cacertoption.
IfthisHTTPSserverusesacertificatesignedbyaCArepresentedin
thebundle,thecertificateverificationprobablyfailedduetoa
problemwiththecertificate(itmightbeexpired,orthenamemight
notmatchthedomainnameintheURL).
Ifyou'dliketoturnoffcurl'sverificationofthecertificate,use
the-k(or--insecure)option.最后的一个解决方案curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);返回
UTF-8
1226251301
-1
88222013
[20921191]退款总金额超出交易金额[20150313174732-183]
010651C7B3906F2863B3B1D2FB63A571
1
MD5