paypal TLS 1.2 and HTTP/1.1 Upgrade Microsite
paypal TLS 1.2 and HTTP/1.1 Upgrade Microsite

paypal安全升級技巧

這是paypal安全升級,變更 PayPal 整合,才能繼續接收付款的下篇,我想應該也會有網友覺得,昇級這件事應該跟我無關吧!當然,如果你沒有使用paypal的話又或者你使用的是分享式主機(因為主機商通常會幫你處理好);而不是VPS的話;那麼跟你一點關係都沒有。但一般如果有使用paypal當作收款工具電子商務專門網站,關係就大了,因為通常都是獨立主機,總不能是因為工程師的能力不太夠而停止使用這個收款方式吧!接著讓我們來看看比較複雜的第1部份。

透過paypal官方的文件,這就更不是件容易的事了,首先只有英文版文件,內容密密麻麻一大串,有興趣的人,可以先打開來看看:TLS 1.2 and HTTP/1.1 Upgrade Microsite。接著讓我們來看看實驗結果

TLS 1.2 及 HTTP/1.1 升級

這個部份,講白話了,就是要你的主機在跟paypal連線溝通時能使用最安全的TLS1.2機制。

檢測主機到底是否支援TLS1.2

步驟一:那麼怎麼知道主機有沒有支援呢?先來檢測主機到底是否支援TLS1.2!

首先paypal官方提供了一個測試網址:https://tlstest.paypal.com;但是這個測試網址並無法直接在主機上使用,以Linux Cent OS+Apache+php+openssl的環境為例,可以執行底下指令

php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch));'

如果是符合paypal要求,會出現“PayPal_Connection_OK”;但如果失敗呢?可能就看不到詳細的錯誤訊息,因此我們就會改使用下面的指令,

php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch)); var_dump(curl_error($ch));'

因為有些網友可能無法使用linux console;於是還有網友寫了一小段php的程式,都可以讓我們輕鬆檢測系統環境

檢測系統環境是否支援TLS1.2 php程式

<?php

// Test from PayPal 
echo 'Test if the TLS version is compatible with PayPal:<br/>';
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); 
echo '&nbsp;curl_exec($ch): ';
var_dump(curl_exec($ch));
echo '<br/>&nbsp;curl_error($ch): ';
var_dump(curl_error($ch));
curl_close($ch);

// Test from https://github.com/paypal/adaptivepayments-sdk-php/issues/64
echo '<br/><br/>Another test, get TLS & SSL Version:<br/>';
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$json = json_decode($data);
echo ' TLS Version: ';
echo $json->tls_version;

$curl_info = curl_version();
echo '<br/> SSL Version: ';
echo $curl_info['ssl_version'];
curl_close($ch);

?>

但問題來了,怎麼檢測下來,一直出現這個最常遇到的錯誤代碼呢?

string(17) "SSL connect error"

google一下,發現許多人也碰到一模一樣的問題,於是有人發現了一個問題,因為php中是使用curl,所以需要把curl連線的protocol設定為 TLS 1.2

curl_setopt ($ch, CURLOPT_SSLVERSION, 6); //Integer NOT string TLS v1.2

因此上述的測試程式會變成

php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); curl_setopt($ch, CURLOPT_SSLVERSION, 6); var_dump(curl_exec($ch)); var_dump(curl_error($ch));'

php程式就會變成

<?php

// Test from PayPal 
echo 'Test if the TLS version is compatible with PayPal:<br/>';
$ch = curl_init(); 
curl_setopt ($ch, CURLOPT_SSLVERSION, 6); //Integer NOT string TLS v1.2
curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); 
echo '&nbsp;curl_exec($ch): ';
var_dump(curl_exec($ch));
echo '<br/>&nbsp;curl_error($ch): ';
var_dump(curl_error($ch));
curl_close($ch);

// Test from https://github.com/paypal/adaptivepayments-sdk-php/issues/64
echo '<br/><br/>Another test, get TLS & SSL Version:<br/>';
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$json = json_decode($data);
echo ' TLS Version: ';
echo $json->tls_version;

$curl_info = curl_version();
echo '<br/> SSL Version: ';
echo $curl_info['ssl_version'];
curl_close($ch);

?>

上面這支程式測試出來的結果才是正確的,當然如果你使用的環境和我們不一樣,就又另當別論了。

Test if the TLS version is compatible with PayPal:
 curl_exec($ch): PayPal_Connection_OKbool(true) 
 curl_error($ch): string(0) "" 

Another test, get TLS & SSL Version:
TLS Version: TLS 1.0
SSL Version: NSS/3.19.1 Basic ECC

步驟二:更新NSS及curl

如果過程都這麼順利的話,又怎麼會有這一篇的存在呢?而且根據我們的經驗,在google了所有相關文件後,基本上也找不到真正的解決方法;所以如果今天你剛好和我們的環境相似,那麼或許這篇文件可以幫到你,幫你省下一大筆的錢和時間。

問題點來了,話說,我們先在測試主機上實驗完成2以後,接著的1呢!不會過,但那時真正的問題點出在「沒有為curl設定正確的protocol」,加了上面那一行程式以後呢?就正常了。接著我們就到production的主機上輕鬆的完成了2,但是1呢?使用正確的程式確依然無法通過paypal檢測。依然出現最令人害怕又無法解決的錯誤

string(17) “SSL connect error”

於是我們確定了php版本…;最後查到curl,開始查看curl的版本

檢查測試主機

curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

更新正式主機

curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

如果沒仔細看,會覺得應該都是一樣的,但是從第一行裡發現,雖然curl都是7.19.7但是正式主機的NSS版本比測試主機舊,也少了Basic ECC;於是我們作了NSS的更新

yum update NSS

更新完後,執行curl -V查看版本資訊,發現還是一樣,於是接著再執行curl更新

yum update curl

更新完成以後,再將apahce重新啓動,就發現正式主機和測試主機的curl版本資訊完全一樣。再執行php的測試程式,就發現成功了。你就可以再輕鬆的繼續使用paypal收款囉!

本文章,為原創內容,歡迎轉貼連結分享,未經同意,禁止全文轉載。

參考資料:

自已實驗

http://stackoverflow.com/questions/30145089/tls-1-2-not-working-in-curl

https://curl.haxx.se/docs/ssl-compared.html

https://github.com/paypal/PayPal-PHP-SDK/issues/484

http://forums.hostgator.com/paypal-security-upgrades-t341008.html?s=3a0dd9b947b9c51e17487ed2acfd29d4&

https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&ID=FAQ1914&viewlocale=en_US

5 評論

  1. 傑克老師:您好
    我的網站並沒有使用https://www.xxx.com/ 這樣的方式,是否就代表沒有申請ssl憑證?
    我根據您提供的PHP代碼,查詢後的結果和您的結果一樣。環境也是CENTOS 6的

    Test if the TLS version is compatible with PayPal:
    curl_exec($ch): PayPal_Connection_OKbool(true)
    curl_error($ch): string(0) “”

    Another test, get TLS & SSL Version:
    TLS Version: TLS 1.0
    SSL Version: NSS/3.19.1 Basic ECC

    請問這樣是否代表已經可以正常使用PAYPAL收款了呢? 是否需要更新 TLS的版本到 TLS 1.2?

      • 謝謝老師的解答,已經成功解決。
        關於SSL憑證,免費的和收費的顯示並不一樣。安全提示影響客戶體驗。
        另外想了解一下,是否使用HTTPS影響訪問速度及對SEO較為不利。請老師指導和建議。

        • 1.關於SSL憑證,的確免費和付費顯示的憑證最大的差異如您所說其實是就是可信度,但在台灣大部份的人會希望可以用免費的東西,所以我就先建議你用囉!如果是正式環境,我就會使用需要花錢的,例如: comodo… 我是去這裡買的 http://ssls.com/
          2.至於影響速度這一方向,可以用 mod_spdy(apache 2.2),但以現在主機的能力,通常影響應該不大(看看google, fb …等都有用),不過這也是一種取捨,google 提到https可以增加seo,但卻也可能讓速度變慢,而造成pagespeed分數下降而造成seo下降,而兩者之間到底seo比例多少,目前似乎沒有確定的答案;所以如果主機速度夠快,也許你也不用擔心;記得一開始我的考量點,也跟你一樣,但使用一陣子之後考量點反而不是了;現在我只有使用 mod_pagespeed,有支援ssl。

回覆留言

Please enter your comment!
Please enter your name here