PHP 5.6 SSL证书验证

10

我正在尝试调试ssl证书验证问题,并确定openssl获取证书路径时返回了不正确的路径。(如下所示)

我该如何找出如何设置它?我查看了php.ini文件,但无法在任何地方找到此引用。

cmuench-air:bin cmuench$ ./php -r "print_r(openssl_get_cert_locations());"
Array
(
    [default_cert_file] => /bitnami/mampstack56Dev-osx-x64/output/common/openssl/cert.pem
    [default_cert_file_env] => SSL_CERT_FILE
    [default_cert_dir] => /bitnami/mampstack56Dev-osx-x64/output/common/openssl/certs
    [default_cert_dir_env] => SSL_CERT_DIR
    [default_private_dir] => /bitnami/mampstack56Dev-osx-x64/output/common/openssl/private
    [default_default_cert_area] => /bitnami/mampstack56Dev-osx-x64/output/common/openssl
    [ini_cafile] => 
    [ini_capath] => 
)

php.ini(相关部分)...我没有看到bitnami/mampstack56Dev的任何地方...

[openssl]
; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context
; option.
;openssl.cafile=

; If openssl.cafile is not specified or if the CA file is not found, the
; directory pointed to by openssl.capath is searched for a suitable
; certificate. This value must be a correctly hashed certificate directory.
; Most users should not specify a value for this directive as PHP will
; attempt to use the OS-managed cert stores in its absence. If specified,
; this value may still be overridden on a per-stream basis via the "capath"
; SSL stream context option.
;openssl.capath=

;Curl ca bundle certificate
curl.cainfo="/Applications/phppos/common/openssl/certs/curl-ca-bundle.crt"

编辑:

我知道这很愚蠢,但有时ssl证书将是自签名的。有没有ini设置我可以修改以禁用检查所有证书?还是我必须在sockets和curl的代码中进行配置?


那些 bitnami/mampstack 路径是通过调用本地 OpenSSL 函数返回的操作系统管理路径。这些默认路径是基于 OpenSSL 安装路径定义的:请参见 http://docs.huihoo.com/doxygen/openssl/1.0.1c/cryptlib_8h.html#a632c06aa262d7c398d82f89f50f636bf。您可能需要手动编写路径到您的脚本中以查找适当的证书或将它们放在该目录中。 - drew010
那些路径是硬编码在二进制文件中的吗?我无法真正获取到它们吗? - Chris Muench
它们最终被硬编码,因为它们是根据 OpenSSL 的配置选项在软件配置和编译时编译进去的。 - drew010
1个回答

11
如果您查看openssl_get_cert_locations()函数的PHP源代码,它会通过调用各种OpenSSL函数(如X509_get_default_cert_file)以及查看php.ini中描述hereopenssl.cafileopenssl.capath值来获取这些位置。
您到底要查找哪些证书/路径? 如果您想获取CA捆绑文件,您可以设置上述引用的php.ini值,以便它们由openssl_get_cert_locations返回。
默认的 PHP 5.6 php.ini 文件没有这些 OpenSSL ini 设置的默认设置,因为它们需要手动定义。此配置位于 php.ini 结尾附近。
[openssl]
; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context
; option.
;openssl.cafile=

; If openssl.cafile is not specified or if the CA file is not found, the
; directory pointed to by openssl.capath is searched for a suitable
; certificate. This value must be a correctly hashed certificate directory.
; Most users should not specify a value for this directive as PHP will
; attempt to use the OS-managed cert stores in its absence. If specified,
; this value may still be overridden on a per-stream basis via the "capath"
; SSL stream context option.
;openssl.capath=

使用cURL时,您可以使用选项CURLOPT_CAINFO来提供一个包含一个或多个证书以验证对等方的完整路径文件,方法是使用curl_setopt()
curl_setopt($ch, CURLOPT_CAINFO, "/path/to/ca/bundle");

这也可以在 php.ini 中设置:

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
;curl.cainfo =

我只是尝试获取有效的路径,但找不到。 我将在查找这些设置后使用我的php.ini更新问题。 - Chris Muench
@ChrisMuench 刚刚更新了答案,加入了禁用检查 fsockopen 和 curl 的选项。 - drew010
@ChrisMuench 那个流函数是 fsockopen 的替代品,它返回相同类型的资源,只是让您对连接和参数拥有更多控制。SSL 选项也适用于 TLS 连接,如果您不使用 SSL/TLS,则不会产生任何影响(或者您可以在非 SSL/TLS 连接上调用普通的 fsockopen,在 SSL/TLS 连接上调用 stream_socket_client)。 - drew010
@drew010 你应该在你的回答中加上一条注释,说明禁用CURLOPT_SSL_VERIFYPEER等选项会导致中间人攻击。 - mbomb007
这个答案对我来说不起作用。default_cert_dir 显示了一个非常旧的 cert dir,它已经不存在了,而且网络搜索也没有显示任何改变 openssl 中 cert dir 的方法。是的,我重新安装了 openssl,但它没有要求我输入任何目录路径。 - David Spector
显示剩余12条评论

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