在 php 中使用 curl 与单独文件中的客户端证书和私钥
Posted
技术标签:
【中文标题】在 php 中使用 curl 与单独文件中的客户端证书和私钥【英文标题】:Using curl in php with client certificate and private key in separate files 【发布时间】:2012-07-03 17:29:45 【问题描述】:我需要一些帮助来重写这个在一个文件中使用 *.pem
(CA cert
)、Client cert
和 private key
的 php curl 代码:
curl_setopt($curl, CURLOPT_URL, $this->url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSLCERT, $this->keystore);
curl_setopt($curl, CURLOPT_CAINFO, $this->keystore);
curl_setopt($curl, CURLOPT_SSLKEYPASSWD, $this->keystorepassword);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
因此它可以在单独的文件中使用CA certificate
、Client Certificate
和Private Key
。
在这个命令行示例中:
curl -d "var1=value1&var2=value2&..." -G -v --key key.pem --cacert ca.pem --cert client.pem:xxxxxx https://www.somesite.com/page
【问题讨论】:
【参考方案1】:这是一个 PHP 脚本,其中包含您的命令行调用的文字翻译:
<?php
$data = "var1=value1&var2=value2&...";
$url = "https://www.somesite.com/page";
$keyFile = "key.pem";
$caFile = "ca.pem";
$certFile = "client.pem";
$certPass = "xxxxxx";
// Initialise cURL
$ch = curl_init($actualUrl);
// The -d option is equivalent to CURLOPT_POSTFIELDS. But...
// PHP's libcurl interface does not implement the -G flag - instead you would
// append $data to $url like this:
$actualUrl = $url.'?'.$data;
curl_setopt($ch, CURLOPT_URL, $actualUrl);
// The -v flag only makes sense at the command line, but it can be enabled
// with CURLOPT_VERBOSE - in this case the information will be written to
// STDERR, or the file specified by CURLOPT_STDERR. I will ignore this for
// now, but if you would like a demonstration let me know.
// The --key option - If your key file has a password, you will need to set
// this with CURLOPT_SSLKEYPASSWD
curl_setopt($ch, CURLOPT_SSLKEY, $keyFile);
// The --cacert option
curl_setopt($ch, CURLOPT_CAINFO, $caFile);
// The --cert option
curl_setopt($ch, CURLOPT_SSLCERT, $certFile);
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $certPass);
/*
Now we should get an identical request to the one created by your command
line string, let's have a look at some of the other options you set...
*/
// CURLOPT_HEADER is disabled by default, there's no need for this unless you
// enabled it earlier
//curl_setopt($ch, CURLOPT_HEADER, 0);
// Your command line string forces a GET request with the -G option, are you
// trying to POST or GET?
//curl_setopt($ch, CURLOPT_POST, true);
// We don't need body data with a GET request
//curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
// Since we've gone to all the trouble of supplying CS information, we might
// as well validate it!
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
【讨论】:
非常感谢,我一回到家就试试这个。 啊哈哈!为了理解CURLOPT_CAINFO
等同于--cacert
标志,我花了几个小时才找到这个注释良好的示例。我一直在傻傻地使用CURLOPT_SSLCERT
——现在看起来很明显。荣誉,@DaveRandom。
我终于到家了。很高兴它帮助了你们两个。
curl_setopt($curl, CURLOPT_URL, $actualUrl);
中的 $curl 也应该是 $ch,不是吗?
您将 *.crt 和 *.key 文件放在哪里?从当前目录加载它们不安全吗?如果您从其他任何地方加载,则 600 权限不允许您的服务器(www-data)读取此文件,如果您允许 640,则会出现权限过多的错误...以上是关于在 php 中使用 curl 与单独文件中的客户端证书和私钥的主要内容,如果未能解决你的问题,请参考以下文章
将cURL与PHP文件中的Google Apps Script Web App一起使用时遇到问题
Heroku(Cedar) + Node + Express + Jade 子目录中的客户端 javascript 文件在本地与 foreman+curl 一起工作,但在推送到 Heroku 时不能