php - 如何使用 GuzzleHttp/cURL 指定公共(public)证书

标签 php laravel ssl curl guzzle

我已经为这个问题奋斗了一段时间,但似乎无法解决。作为序言,这是我第一次使用 SSL。我正在使用的服务器使用 PHP 5.6.30 和 Laravel 5.1.46,我正在尝试使用 GuzzleHttp 6.2.3 将 JSON 发布到第三方。到目前为止,我一直通过在客户端中指定 'verify' => false 来禁用 ssl 验证,并且能够获得成功的响应。第三方给我提供了证书使用,给了我.pem和.cer两种格式。他们说证书不受密码保护,因为它是公钥。根据 GuzzleHttp 的文档,我的请求应该是这样的:

$response = $client->request('POST', $endpoint, [
    'cert' => /path/to/new/cert.pem,
    'headers' => [
      'Content-type' => 'application/json'
    ],
    'body' => $request_body,
    'connect_timeout' => 5,
]);

我无法使用此方法连接,不幸的是,由于我正在使用的服务器的设计,我无法获得低级错误详细信息(这是一个大型的预先存在的代码库,我必须更新它,它希望最终会被完全重写)。

为了获得更多细节,我决定使用 cURL 发送请求。首先我发送了没有证书的请求:

// REQUEST
curl -v -H "Content-Type: application/json" -X POST -d '{"some_json_request": "value"}' https://sometargeturl.com:8443/dosomething

// OUTPUT
*   Trying 204.71.178.10...
* TCP_NODELAY set
* Connected to sometargeturl.com (204.71.178.10) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Server certificate:
*   subject: CN=sometargeturl.com,OU=OU,O="Some Company Name, Inc",L=Pleasanton,ST=California,C=US
*   start date: May 13 00:00:00 2016 GMT
*   expire date: May 14 23:59:59 2018 GMT
*   common name: sometargeturl.com
*   issuer: CN=Symantec Class 3 Secure Server CA - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
* NSS error -8179 (SEC_ERROR_UNKNOWN_ISSUER)
* Peer's Certificate issuer is not recognized.
* Curl_http_done: called premature == 1
* Closing connection 0
curl: (60) Peer's Certificate issuer is not recognized.

然后,有了证书:

// REQUEST
curl -v --cert /path/to/the/cert.pem -H "Content-Type: application/json" -X POST -d '{"some_json_request": "value"}' https://sometargeturl.com:8443/dosomething

// OUTPUT
*   Trying 204.71.178.10...
* TCP_NODELAY set
* Connected to sometargeturl.com (204.71.178.10) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* unable to load client key: -8178 (SEC_ERROR_BAD_KEY)
* NSS error -8178 (SEC_ERROR_BAD_KEY)
* Peer's public key is invalid.
* Curl_http_done: called premature == 0
* Closing connection 0
curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY)

我进行了大量研究,但未能找到解决方案。在这一点上,我真的不确定接下来的步骤。我最终将需要使用 GuzzleHttp 来发送请求,但我不知道我缺少什么。我已经阅读了有关将新证书添加到现有 CA bundle 的信息,但是我不确定这是否是正确的解决方案/如果是这样我会怎么做。任何帮助将不胜感激,谢谢!

最佳答案

你到底想做什么?

  • 使用 'verify' => true 验证远程服务器证书
  • 通过向远程出示您的证书来验证您自己?

也就是说,您的 curl 是针对 NSS 而不是 openssl 编译的。 NSS 错误 -8178 (SEC_ERROR_BAD_KEY) 来自不支持将私钥作为文件提供的 NSS

关于php - 如何使用 GuzzleHttp/cURL 指定公共(public)证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46573050/

相关文章:

PHP 不工作,数据库不更新

javascript - Codeigniter 2 - 插入表会创建重复项

php - 连接字符串错误,PHP 与 Azure 中部署的 MySQL

php - 在 VSCode 上调试 Laravel 应用程序

php - 到 Controller 的 laravel 路由被调用两次

ios - 尝试向 iOS 设备发送推送通知 - 未收到它们

php - Laravel 表单输入整数长度

javascript - Vue.js 在每个页面上重置索引和长度

django - 在 Apache 上为 Django 应用程序配置 SSL 证书 (mod_wsgi)

ssl - 在 AWS 上的 ELB EC2 之间添加 SSL 通信并强制仅进行 HTTPS 通信