【问题标题】:How to mutual/two-way authenticate with php curl?如何使用 php curl 进行双向/双向身份验证?
【发布时间】:2019-04-18 20:56:27
【问题描述】:

网站提示“您未使用数字证书进行身份验证,或者连接时间已过期。请使用您的数字证书再次进行身份验证。”。

我每次都收到此消息,因此我认为我的身份验证尝试没有工作,而不是连接时间到期。

我这样做的方式是从一个 pfx 文件和一个打开它的密码开始。我使用 openssl 和 pfx 制作 pem 证书。

代码:

<?php
$pfx_path = 'me.pfx';
$pfx_pass = 'foopass123';
$pfx_values = [];
openssl_pkcs12_read(file_get_contents($pfx_path), $pfx_values, $pfx_pass);
$cert_path = 'me.pem';
file_put_contents($cert_path, $pfx_values['cert'] . "\n" . $pfx_values['pkey']);
$postfields = 'field1=val1&field2=val2&field3=val3';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL           , 'https://www.example.com');
curl_setopt($ch, CURLOPT_POST          , true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS    , $postfields);
curl_setopt($ch, CURLOPT_SSLCERT       , $cert_path);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
$curl_result = curl_exec($ch);
$curl_info = curl_getinfo($ch);
curl_close($ch);

执行代码的结果(仅显示 $curl_result 的 HTML 引用):

您没有使用数字证书进行身份验证,或者可能是 连接时间已过。用数字证书再次认证。

顺便说一句,$curl_info['ssl_verify_result'] 是 0,我猜这意味着至少服务器经过了正确的身份验证。

编辑:删除了CURLOPT_SSLCERTPASSWD,因为它不是必需的,pfx 文件已经用密码打开了,并且它的私钥和公钥被赤裸裸地放入$cert_path

【问题讨论】:

  • 您似乎不太需要设置CURLOPT_SSLCERTPASSWD,因为您已经将信息从 PFX 提取到 PEM。您是否确认正在写入 PEM 文件?
  • @zod 因为回复来自服务器,他们必须已经正确设置了 CA 包。
  • @zod,您链接的代码帮助我发现我缺少站点中特别需要的标题。我从浏览器进行了身份验证并复制了标头,然后我终于进行了身份验证,但是我重用了从浏览器的标头中获得的会话 ID,而且我不知道如何从 php 获取会话 ID,我猜那是在外面问题的范围,所以我猜它已经解决了。
  • @miken32 你是对的,因为这个原因我不需要密码。

标签: php ssl curl


【解决方案1】:

在该特定站点上成功进行身份验证需要标头。缺少的标头是 Cookie: ...,其中包含特定字段,例如会话 ID(您可以通过使用 cURL 登录网站或简单地通过浏览器以用户身份获取,您可以复制并粘贴由服务器)。

您可以指定 Cookie 标头:

curl_setopt($ch, CURLOPT_COOKIE,
    'foo=123;'
    . ' bar=456;'
    . ' SESSIONID=789;'
);

或者你可以指定它:

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Cookie: foo=123;'
    . ' bar=456;'
    . ' SESSIONID=789;'
));

要以一般的方式看待这一点,而不是将问题视为仅限于特定站点的问题,请注意不同的站点将需要不同的标头和 cookie,也可能不需要。

因此,如果您想像用户一样在给定站点中进行相互身份验证,请确保您使用正确的标头和 cookie,以备不时之需。

现在,如何使用 cURL 获取会话 ID,这取决于每个站点,这超出了问题的范围,但一般来说,它是用 PHP 模仿用户在浏览器中执行的相同操作的问题,并且它可能是在站点内的特定 URL 中完成的,而不是所有站点广泛的。

【讨论】:

  • 通常服务器会为您提供 cookie(通过 set-cookie 之类的标头)。然后客户端将进一步的请求发送回同一服务器。客户端不应该通过构造来定义在 cookie 中放入的内容。甚至比从客户端接受任意 cookie(他以前没有自己生成的东西)的服务器更容易受到许多攻击......
  • @PatrickMevzek 确实,为了安全,会话 ID 必须由服务器生成。就我而言,我必须在网站中找到一个返回会话 ID cookie 的 URL,以换取提交具有特定 POST 字段的表单,同时使用客户端证书进行身份验证,然后我可以使用此会话 ID cookie 访问不同的页面网站,直到会话到期。
  • @PatrickMevzek 我澄清了那部分,我并不是说服务器会接受来自客户端的任意 cookie,我希望现在我的编辑清楚了。
猜你喜欢
  • 1970-01-01
  • 2011-05-25
  • 2018-11-12
  • 2020-12-05
  • 2021-09-11
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多