這裏是打開一個SSL套接字準備發送HTTP請求一個簡單的PHP腳本:PHP和SSL CA驗證 - 與操作系統無關
$contextOptions = array(); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); exit; } var_dump($socket); exit('Socket created.');
這工作 - 我只是測試它 - 但沒有驗證針對受信任的CA商店。
我們可以修改腳本,以使用PHP的SSL Context options:
$contextOptions = array( 'ssl' => array( 'cafile' => 'C:\xampp\cacerts.pem', 'CN_match' => '*.google.com', // CN_match will only be checked if 'verify_peer' is set to TRUE. See https://bugs.php.net/bug.php?id=47030. 'verify_peer' => TRUE, ) ); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); exit; } var_dump($socket); exit('Socket created.');
只要「憑證檔案錯誤」存在並具有正確的CA那麼這個例子也適用...
...但我們如何在不對CA文件名/文件路徑進行硬編碼的情況下做到這一點?我們試圖創建一些獨立於操作系統的SSL證書驗證,而不需要爲運行此腳本的每臺服務器單獨配置。
我知道Linux有一個CA的目錄,我們可以把它作爲'capath'。 Windows怎麼樣?它在哪裏存儲其可信CA?我搜索了,這些不幸似乎在註冊表中,那麼我們沒有辦法從PHP訪問它們嗎?其他操作系統呢?
rdlowrey是絕對正確的。但是,您可以從Guzzle中抽出一部分,並在您的代碼中打包自己的CA文件:https://github.com/guzzle/guzzle/blob/master/src/Guzzle/Http/Resources/cacert.pem – Tom 2014-02-27 19:23:02
我應該補充說,當使用curl方法時,您需要負擔確保您的CA證書是最新的。這些通常每年都會發生一些變化,如果不更新,可能存在潛在的問題,您可以使用受到攻擊的CA來驗證對等方。 5.6使用操作系統管理的證書的能力是向前邁進的一大步,因爲您不必知道這些。但是,這也與您安裝最新的操作系統更新的傾向一樣好,因此您的證書不會過時。不幸的是,這是一個很快不會出現在libcurl中的功能。 – rdlowrey 2014-02-27 19:56:39
如果您需要最大限度的安全性(針對偏執狂和NSA意識),最好的解決方案是使用已知的指紋哈希來驗證對等方的證書。這是在PHP 5.6中也可用於加密流的功能。也就是說,有關這些事情的文檔有很多工作要做,所以我們可以在發佈之前的幾個月內發佈這些信息。是的:我們意識到這一點,是的,如果你想保護你的轉賬,我們將努力工作,使手冊成爲一個有用的資源:) – rdlowrey 2014-02-27 19:58:26