在 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 certprivate keyphp 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 certificateClient CertificatePrivate 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一起使用时遇到问题

curl抓取网页内容php

php curl采集,服务器gzip压缩返回数据怎么办

怎么开启curl

Heroku(Cedar) + Node + Express + Jade 子目录中的客户端 javascript 文件在本地与 foreman+curl 一起工作,但在推送到 Heroku 时不能

与mac相比在windows上使用curl的问题