2010-06-30 69 views
4

假设我有一个网络服务器中运行一些PHP代码,例如,运行一个简单的CakePHP的应用程序。从这个应用程序,我想偶尔做一个TLS连接到某些服务器交换一些数据。这通常如何完成? (我有PHP缺乏经验。)如何使Web服务器从PHP TLS连接,并安全地

什么PHP插件或图书馆或什么的,建议完成TLS连接?哪里有一些好的地方可以开始寻找? (我最初的谷歌搜索给我噪声的巨大比例的信号。)

什么是涉及具有X509私钥坐在Web服务器上的安全问题?为了建立一个TLS连接,我将需要X509证书和相应的私钥,或许是PEM文件,DER文件或Java密钥库或其他。那个私钥会被放在web根目录下的某处吗?这通常如何处理?什么是安全问题,特别是保护将用于建立TLS连接的私钥?什么是最佳实践?

编辑:我忘了提的是,PHP应用程序连接到服务器,需要将提交客户端证书。客户端确实需要私钥才能连接到。此外,我连接的服务器是而不是 HTTP服务器 - 我只需要读取/写入服务器的普通套接字连接(通过SSL/TLS连接)。

回答

7

TLS是正确的名称,但大多数人还是把它叫做SSL。在PHP中,您可以建立此连接using CURL

随着TLS/SSL客户端,您只需要公钥来验证远程主机。这个公钥只是公开的,它是否泄露给攻击者并不重要。在服务器端Apache可以访问公钥和私钥。这些密钥受到普通文件访问权限的保护。在* nix系统下,这些密钥通常存储在Apache进程所拥有的/etc/的某处,chmod 400是最好的。

最简单的客户端身份验证方法是简单的用户名/密码。您可以使用SSL来认证客户端和服务器。这需要您将私钥存储在PHP应用有权访问的地方,最理想的情况是使用chmod 400以外的webroot,但您可以轻松地将其重命名为.php或将其放入包含deny from all的.htaccess文件夹中。在服务器端,您可以使用these environmental variables来验证客户端证书。

如果你只是想要一个TLS连接而不是HTTP。然后,你可以通过设置Context Options使用stream_context_set_option:

<?php 
$context = stream_context_create(); 
$result = stream_context_set_option($context, 'ssl', 'local_cert', '/path/to/keys.pem'); 
// This line is needed if your cert has a passphrase 
$result = stream_context_set_option($context, 'ssl', 'passphrase', 'pass_to_access_keys'); 

$socket = stream_socket_client('tls://'.$host.':443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context); 
?> 
+1

我的客户*不*需要一个私钥,因为它需要提供客户端证书到服务器。在这种情况下,将它完全移出Web根目录是不是最好,然后,PHP脚本可以访问它,但它不会被Web服务器(PHP脚本运行)损害? 另外,CURL不让我发送任意数据流,是吗?它看起来像CURL仅在连接到HTTP服务器或FTP服务器时才有用,而我并不知道它。是否有一个通用于简单数据流的类似库? – 2010-07-01 18:49:27

+0

@Jim Flood PHP必须有权访问证书,如果您的PHP应用程序拥有,那么您的证书也是如此,这是没有办法解决的。 CURL应该用于HTTP,如果你只是想要第4层连接,那么你可以使用fsockopen(),检查我的更新。 – rook 2010-07-01 19:02:50

+1

Rook我知道你对私钥的风险意味着什么,因为PHP必须有权访问它。至于fsockopen,我的LAMP安装有PHP5和fsockopen不再有“第六个参数”,但我确实发现stream_socket_client在'ssl'选项(而不是'tls')中与local_cert,cafile和verify_peer协同工作。你能在你的答案中注意到吗?谢谢。 – 2010-07-01 22:47:17