如何在使用tls时使fsockopen忽略证书

4
在PHP7.0中,当使用fsockopen连接打开https连接(托管在同一主机上),使用类似于tls://foo.localhost的主机名时,会出现以下错误:
fsockopen(): Peer certificate CN="bar" did not match expected CN="foo.localhost"

连接未打开。

在 PHP 5.5 中可以正常工作(该版本的证书检查较为宽松)。我并不关心验证证书(此代码仅在单元测试和集成测试中连接到本地主机)。但是需要针对 http 和 https 进行测试。

我知道如何在使用 file_get_contents 时禁用这些检查。

在使用 fsockopen 时,如何禁用对等证书验证呢?


verify_peer 上下文选项 会影响这个吗? - Álvaro González
@ÁlvaroGonzález,我不知道如何将上下文传递给fsockopen函数。 - juanleon
从未使用过套接字,我认为 stream_context_set_default() 应该可以工作。如果不行,请尝试在 fsockopen() 手册页面中建议的函数:"函数 stream_socket_client() 类似,但提供了更丰富的选项,包括非阻塞连接和提供流上下文的能力。" - Álvaro González
@ÁlvaroGonzález,context_set_default在fsockopen中无法正常工作。很可能stream_socket_client是正确的方法(我一开始有所犹豫,因为fsockopen是我需要使用的不太现代的测试库的核心)。感谢您指出这一点。 - juanleon
1个回答

15

fsockopen 不提供忽略对等证书错误的方法。

您需要使用stream_socket_clientcontext。可用的 SSL/TLS 上下文选项请参见此处

打开不进行对等验证的套接字的示例:

$context = stream_context_create([
    'ssl' => [
        'verify_peer' => false,
        'verify_peer_name' => false
    ]
]);

$hostname = "tls://foo.localhost:8123";
$socket = stream_socket_client($hostname, $errno, $errstr, ini_get("default_socket_timeout"), STREAM_CLIENT_CONNECT, $context);

在某些奇怪的 DEV 主机名的情况下,正确的选项 'verify_peer_name' => false 可能是必要的。 - DonRico
如何使用stream_socket_client而不是fsockopen来指定端口? - Shadi Alnamrouti
@ShadiNamrouti 你可以在 $hostname 中包含端口,例如 $hostname = "tls://foo.localhost:8123"; - mleko

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