2010-06-30 67 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