PHP(直到最近才与python一起使用)存在一个长期存在的安全问题,即所有使用SSL / TLS的函数都不执行证书验证,因此只要站点提供某种有效的证书,即使它未由已知CA签名,或者与域不匹配,也将被允许。这当然意味着它很容易受到中间人攻击。
PHP 5.6通过this PHP RFC的实现解决了这个问题。其中很大一部分是新的php.ini属性openssl.capath
,它指向CA证书文件夹,它是主机平台上OpenSSL的一部分,可以被PHP的SSL流上下文用作capath
属性( docs)。 A second RFC添加了一个函数openssl_get_cert_locations()
,以便更轻松。
这对于PHP 5.6来说非常棒,但找到CA证书路径对于早期版本来说并不是一个容易解决的问题,这对每个人来说都意味着5.6还没有发布。
在大多数Linux发行版上,这条路径都是/etc/ssl/certs
,但对于在Windows,BSD,OS X等上运行的可移植代码而言,这不是一个可靠的假设。为了解决这个问题,OS X特别麻烦,因为OS X上的OpenSSL没有将CA证书存储在文件系统中但存储在系统密钥链中。
对于任何特定平台来说,这当然很容易解决,因为您可以在您的服务器上设置适当的内容,但在这种情况下,它适用于一些非常流行的库代码,这些代码在整个地方使用。
任何人都可以建议一种可靠的跨平台方式来查找CA证书路径吗?
答案 0 :(得分:2)
首先,我要感谢您知道应该检查证书。不幸的是,大多数人只是忍受着不安全的默认设置,并且很高兴没有错误被抛出。
但对你的问题: OpenSSL不使用OS X上的钥匙串(另请参阅http://landonf.bikemonkey.org/code/macosx/certsync.20130514.html)。所有平台openssl以相同的方式确定默认位置(请参阅openssl源中的crypto / cryptlib.h):
openssl version -d
或调用PHP中应该可用的函数SSLeay_version(5)
来获取OPENSSLDIR的值。这些设置通常适用于Linux和* BSD系统,因为它们的证书安装在预期的位置,但在Windows和OSX上失败,它们自己的证书管理与openssl不兼容。因此,在此平台中,您需要找到转换内置CA的方法,或者只使用Mozilla中的CA捆绑包,转换为PEM。您可以在http://curl.haxx.se/ca/cacert.pem
找到此信息 编辑:我刚刚读到,OS X上的本机openssl被Apple修补,以增加对TEA的支持(例如集成到keychain中)。虽然添加方式有问题,但请参阅https://hynek.me/articles/apple-openssl-verification-surprises/了解详细信息。