如何在fsockopen中启用SSL?

21

我在Windows上运行PHP 5.2.6,我的php.ini中取消了extension=php_curl.dllextension=php_openssl.dll的注释;因此我可以在phpinfo中看到如下信息:

curl
cURL support        enabled
cURL Information    libcurl/7.16.0 OpenSSL/0.9.8g zlib/1.2.3

openssl
OpenSSL support     enabled
OpenSSL Version     OpenSSL 0.9.8g 19 Oct 2007

我不确定启用cURL是否对此至关重要,但由于它提到了OpenSSL,我认为为了完整起见还是包含在这里。


我想做的很简单:使用fsockopen通过SSL向另一个服务器发出POST请求。
到目前为止,我的代码是这样的:

$host = 'www.redacted.com';
$data = 'user=redacted&pass=redacted&action=redacted';
$response = "";

if ( $fp = fsockopen("ssl:{$host}", 443, $errno, $errstr, 30) ) {

    $msg  = 'POST /wsAPI.php HTTP/1.1' . "\r\n";
    $msg .= 'Content-Type: application/x-www-form-urlencoded' . "\r\n";
    $msg .= 'Content-Length: ' . strlen($data) . "\r\n";
    $msg .= 'Host: ' . $host . "\r\n";
    $msg .= 'Connection: close' . "\r\n\r\n";
    $msg .= $data;
    if ( fwrite($fp, $msg) ) {
        while ( !feof($fp) ) {
            $response .= fgets($fp, 1024);
        }
    }
    fclose($fp);

} else {
    $response = false;
}

当然,如果我只传入$host并使用端口80,那么这可以正常工作。但我真的需要通过SSL发送,但现在它无法正常工作。$response设置为false$errno保持为0$errstr设置为php_network_getaddresses: getaddrinfo failed: No such host is known.。我知道这不是服务器宕机或主机名中有拼写错误等问题,因为如果我未加密地使用端口80,则可以正常工作。问题仅在我尝试切换到SSL时开始。

我该怎么做才能让它正常工作?


不是很相关于答案,但您是否考虑使用TLS协议呢?TLSv1本质上是SSL的第四个版本,并已广泛取代它成为事实上的SSL实现。 - Powerlord
只是一条注释,以确保读者知道TLSv1.0因不够安全而被弃用,以及所有版本的SSL。请参阅https://en.wikipedia.org/wiki/Transport_Layer_Security。 - David Spector
@DavidSpector 没错,但我希望人们使用更新的TLS版本,考虑到这个问题今天已经10年了。TLS 1.3是最新的版本,实际上是SSL的第七个版本。 - Powerlord
解决的一个更普遍的问题是如何消除在Web上发布的信息,这些信息曾经很好,但随着时间的推移变得糟糕。我想不出一个好的解决方案,但我有一种感觉,一个好的解决方案是可能的。 - David Spector
1个回答

61

这可能听起来很明显,但你尝试过这个吗?

if ($fp = fsockopen('ssl://'. $host, 443, $errno, $errstr, 30)) {

我不确定是否需要 //,但是PHP网络传输页面上的 ssltls 示例都包含它们。

P.S. 如果你想知道为什么现在使用字符串连接,那是因为我对字符串中包括变量有一些“固执”的想法。


天啊,我感觉自己像个白痴。只需要这个就可以了!非常感谢。我也不介意包含变量和连接变量的小问题。我们都有自己的怪癖。 - soapergem
这在我尝试发送电子邮件时在另一个应用程序中无法正常工作。当我以不安全的方式发送并且服务器接受不安全的发送时,它可以正常工作,但如果我对方案和端口进行更改,则无法正常工作。我会得到一个无限循环。 - David Spector
我真是太蠢了。我的端口是25,所以电子邮件的安全端口必须是465,而不是443。通过这个更改,我的代码成功发送了一封电子邮件(并将我的服务器设置为安全)。我已经编辑了这个答案。 - David Spector
@DavidSpector 对于电子邮件,这是一个关于服务器是否支持SMTP上的TLS或者支持SMTPS的问题。前者在25号端口上,后者在465号端口上。 - Powerlord
端口25(不安全的邮件服务器访问)不应再使用。它会使您的邮件服务器暴露于恶意用户的攻击,并且几乎没有任何好处。我赞同Let's Encrypt项目的观点,即整个Web(和电子邮件)都应该变得更加安全。 - David Spector

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接