1. 程式人生 > >使用 BoringSSL 優化 HTTPS 加密演算法選擇

使用 BoringSSL 優化 HTTPS 加密演算法選擇

提醒:本文最後更新於 1170 天前,文中所描述的資訊可能已發生改變,請謹慎使用。

前不久,一位朋友在我部落格評論中,問到:類似於 Google 那樣電腦訪問使用 AES,手機訪問使用 CHACHA20 的演算法是怎麼實現的(詳情)。最近我研究了一下這個問題,現在我的部落格也支援這個特性了。今天抽空介紹一下我的實現步驟,供喜歡折騰的朋友們參考。

對稱內容加密

我們知道,每個 TLS 會話都是在握手階段通過非對稱加密得出對稱加密金鑰,而本次會話雙方一直會用這個金鑰進行流量的對稱加密。這樣做是出於效能考慮,畢竟對稱加密速度要快得多,更適合全流量使用。

對稱加密演算法有流式、分組兩種。RC4 就是一個常見的流式加密演算法,不過已被證實不再安全,應該停止使用。Google 推出了一種名為 ChaCha20-Poly1305 的流式加密新演算法,已經內置於各大平臺的 Chrome 之中。ChaCha20 除了更安全,還針對 ARM 做了優化,在移動裝置上使用速度更快、更省電。以下是它與 AES-GCM 在加密速度上的對比(

via):

chacha20 poly1305

AES-GCM 是目前推薦使用的分組加密模式,它的缺點是計算量大,導致效能和電量開銷比較大。為此,Intel 推出了一個名為 AES NI(Advanced Encryption Standard new instructions)的 x86 指令集擴充套件,從硬體上提供對 AES 的支援(詳情)。Intel 自家 CPU 從 Westmere 平臺開始支援 AES-NI,目前在 PC 端 AES-NI 的普及率顯然很高。對於支援 AES-NI 的裝置來說,使用 AES-GCM 加密演算法無疑是最優選擇,以下是一份對比(測試使用支援 AES-NI 的 Intel Xeon E3-1220 V2 @ 3.10GHz,

via):

Did 20341000 AES-128-GCM (16 bytes) seal operations in 3000099us (6780109.6 ops/sec): 108.5 MB/s
Did 2356000 AES-128-GCM (1350 bytes) seal operations in 3000761us (785134.2 ops/sec): 1059.9 MB/s
Did 438000 AES-128-GCM (8192 bytes) seal operations in 3002910us (145858.5 ops/sec): 1194.9 MB/s
Did 17839000 AES-256-GCM (16 bytes) seal operations in 3000160us (5946016.2 ops/sec): 95.1 MB/s
Did 2092000 AES-256-GCM (1350 bytes) seal operations in 3000884us (697127.9 ops/sec): 941.1 MB/s
Did 388000 AES-256-GCM (8192 bytes) seal operations in 3004207us (129152.2 ops/sec): 1058.0 MB/s
Did 7779000 ChaCha20-Poly1305 (16 bytes) seal operations in 3000332us (2592713.1 ops/sec): 41.5 MB/s
Did 1139000 ChaCha20-Poly1305 (1350 bytes) seal operations in 3001412us (379488.1 ops/sec): 512.3 MB/s
Did 220000 ChaCha20-Poly1305 (8192 bytes) seal operations in 3006395us (73177.3 ops/sec): 599.5 MB/s

可以看到,儘管純軟體實現的 ChaCha20 演算法已經十分優秀,但跟有 AES-NI 加持的 AES-GCM 比起來還是差距明顯。

綜上,我們很容易想到「僅針對支援 AES-NI 的終端使用 AES-GCM 演算法,否則使用 ChaCha20」無疑是一個非常完美的方案。

BoringSSL

之前文章介紹過,基於 LibreSSL 編譯 Nginx,可以輕鬆地使用 ChaCha20。但問題是一旦配置了 ChaCha20,只要終端支援,無論桌面裝置還是移動裝置都會使用它。

BoringSSL 是 Google 從 OpenSSL 拉出來的一個獨立發展的分支,目前跟 OpenSSL 相比已經有很多不同之處了。BoringSSL 支援了一種名為「等價加密演算法組(Equal preference cipher groups)」的配置(詳情),正好可以滿足我們這個需求。

基於 BoringSSL 編譯 Nginx 之後,可以像下面這樣配置 ssl_ciphers

ssl_ciphers [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:DES-CBC3-SHA;

方括號之中的配置就是「等價加密演算法組」,用豎線隔開的兩種演算法,會被自動應用於最合適的場景(支援 AES-NI 優先使用 AES-GCM,否則優先使用 ChaCha20)。最後的 DES-CBC3-SHA 是為了支援 Windows XP 上的 IE8 而加上去的。

下圖中,同樣是訪問本部落格,左側是 Mac Chrome 的截圖,右側是 iPhone Chrome 的截圖:

aes chacha20

可以看到(現在應該看不到,我為了測試其他功能又切回了 LibreSSL),只有移動端才使用了 ChaCha20。

這裡簡單介紹一下「等價加密演算法組」的原理:我們知道客戶端建立 TLS 連線時,在傳送的 Client Hello 中會帶上自己支援的加密演算法,供服務端從中挑選。由於老舊客戶端會支援一些不安全的加密演算法,為了提高傳輸安全,通常會在服務端指定一個可用演算法列表,最終使用的加密型別取決於二者的交集,並按服務端優先順序取第一個;如果沒有交集,直接終止會話。在 Nginx 中這個功能通過將 ssl_prefer_server_ciphers 設定為 on 開啟。

那麼問題來了,對於同時支援 AES-GCM 和 ChaCha20 的 Chrome 來說,服務端列表無論把哪個放前面都會導致另外一個完全沒機會被選中。而「等價加密演算法組」的意義在於,等價組內的演算法具有相同優先順序。這樣,客戶端可以把想要優先使用的加密演算法放在前面。舉例說明二者的區別(開啟 ssl_prefer_server_ciphers 條件下):

  • 不支援等價組時,如果服務端列表是:A、B、C,瀏覽器 1 支援:A、B,最終使用 A;瀏覽器 2 支援 B、A,最終使用 A,瀏覽器 3 支援 C、A,最終使用 A
  • 支援等價組時,如果服務端列表是:[A|B]、C,瀏覽器 1 支援:A、B,最終使用 A;瀏覽器 2 支援 B、A,最終使用 B,瀏覽器 3 支援 C、A,最終使用 A

可以看到,開啟 ssl_prefer_server_ciphers 可以讓會話使用最安全的加密演算法(前提是服務端配置正確),而「等價加密演算法組」還可以讓瀏覽器有區域性調整的許可權。

補充一下通過 Mac Chrome 和 iPhone Chrome 分別訪問我的部落格傳送的加密演算法列表(使用 wireshark 抓包,在 Client Hello 握手中可獲得):

Mac Chrome:
Cipher Suites (17 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc14)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc13)
Cipher Suite: TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc15)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)

iPhone Chrome:
Cipher Suites (15 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc14)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcc13)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)

可以看到,Chrome 瀏覽器確實是會在不同平臺上傳送不同順序的演算法列表,只要服務端配置了「等價加密演算法組」就可以實現本文所描述的功能。

最後提醒大家:現階段 BoringSSL 不支援 OCSP Stapling。改用 BoringSSL 後,如果在 ssllabs 測試中發現這一項變成 off 不要吃驚。

詳細配置步驟

之所以把這部分內容放在最後,是因為折騰起來有點費勁,嫌麻煩的同學可以直接忽略之後所有內容。

以下步驟在我兩臺系統為 Ubuntu 14.04.3 的 VPS 上都能正常執行。如果你遇到了問題,請留言指出。

首先,獲取編譯所需的 Nginx 和 BoringSSL 原始碼,Nginx 從 1.7.4 開始支援 BoringSSL,這裡我直接使用最新版:

wget http://nginx.org/download/nginx-1.9.6.tar.gz
tar xzf nginx-1.9.6.tar.gz

git clone https://boringssl.googlesource.com/boringssl

現在,當前目錄下應該有這兩個子目錄:

boringssl/
nginx-1.9.6/

確認無誤後,還要做一些準備工作:

# 安裝編譯 BoringSSL 所需的 Golang
sudo apt-get install golang

# 安裝編譯 Nginx 所需的工具和依賴庫
sudo apt-get install build-essential libpcre3 libpcre3-dev zlib1g-dev

# 忽略編譯過程中的 Warning(不加這個,編到一半會因為 Warning 太多無法繼續)
export CFLAGS="-Wno-error"

編譯 BoringSSL:

# 進入 BoringSSL 原始碼根目錄
cd boringssl

# 建立 build 目錄並編譯,完成後回到 BoringSSL 原始碼根目錄
mkdir build && cd build && cmake ../ && make && cd ../

# 建立 .openssl 目錄,並將庫檔案和編譯後的檔案放進去
mkdir -p .openssl/lib && cd .openssl && ln -s ../include . && cd ../
cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib

cd ../

現在可以編譯 Nginx 了:

# 進入 Nginx 原始碼根目錄
cd nginx-1.9.6

# 指定使用 BoringSSL 作為 SSL 庫
./configure --with-openssl=../boringssl --with-http_v2_module --with-http_ssl_module

# 修改時間,避免 Nginx 再次編譯 BoringSSL
touch ../boringssl/.openssl/include/openssl/ssl.h

touch 後可以開始 makemake install 了。這期間可能還會遇到這樣一個報錯:

'SSL_R_BLOCK_CIPHER_PAD_IS_WRONG' undeclared

這是因為 BoringSSL 刪掉了這個變數。找到報錯檔案 src/event/ngx_event_openssl.c 中對應的位置:

    || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */

刪掉這一行,或者加個判斷都可以解決問題:

#ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG
    || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */
#endif

其他應該沒什麼問題了。make install 之前記得先停掉 nginx 服務,不然很可能需要手動殺死之前的 nginx 程序。一切妥當後,參考前文修改 ssl_ciphers 並啟動服務,搞定收工!

更新:

使用 OpenSSL 1.0.2 加上 CloudFlare 的 patch,也可以實現本文一樣的效果,同時還可以支援 OCSP Stapling,更為推薦!詳見 neveta 的這篇文章:《Patch Openssl 使其支援 chacha20 演算法》。

--EOF--

提醒:本文最後更新於 1170 天前,文中所描述的資訊可能已發生改變,請謹慎使用。

相關推薦

使用 BoringSSL 優化 HTTPS 加密演算法選擇

提醒:本文最後更新於 1170 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 前不久,一位朋友在我部落格評論中,問到:類似於 Google 那樣電腦訪問使用 AES,手機訪問使用 CHACHA20 的演算法是怎麼實現的(詳情)。最近我研究了一下這個問題,現在我的部落格也支援這個特性了。今天

【百度】大型網站的HTTPS實踐(二)——HTTPS加密演算法介紹

大型網站的HTTPS實踐(二)——HTTPS加密演算法介紹 原創 網路通訊/物聯網 作者:AIOps智慧運維 時間:2018-11-09 15:09:43  358  0   前言

HTTP和HTTPS的區別及HTTPS加密演算法

HTTPS協議的埠是443,HTTP協議的埠是80,其中HTTPS是相對安全的 HTTP是超文字傳輸協議 應用層協議 FTP、Telnet、SMTP、HTTP、RIP、NFS、DNS。 傳輸層協議的有 TCP協議、UDP協議 HTTP和HTTPS的概念        

HTTPS的中那些加密演算法

密碼學在電腦科學中使用非常廣泛,HTTPS就是建立在密碼學基礎之上的一種安全的通訊協議。HTTPS早在1994年由網景公司首次提出,而如今在眾多網際網路廠商的推廣之下HTTPS已經被廣泛使用在各種大小網站中。在完全理解HTTPS之前,有必要弄清楚一些密碼學相關的概念,比如:明文、密文、密碼、

HTTPS中的加密演算法相關概念

密碼學在電腦科學中使用非常廣泛,HTTPS就是建立在密碼學基礎之上的一種安全的通訊協議。HTTPS早在1994年由網景公司首次提出,而如今在眾多網際網路廠商的推廣之下HTTPS已經被廣泛使用在各種大小網站中。在完全理解HTTPS之前,有必要弄清楚一些密碼學相關的概念

加密解密流程和各加密演算法選擇、用途

加密演算法的分類: 雙向加密:分為對稱加密和非對稱加密。 對稱加密 採用單鑰密碼系統的加密方法,同一個金鑰可以同時用作資訊的加密和解密,這種加密方法稱為對稱加密,也稱為單金鑰加密。  需要對加密

Https核心加密演算法-Diffie–Hellman key exchange

Diffie–Hellman key exchange 演算法描述: 公鑰演算法的特點就是很容易由運算元計算出結果,而基本上不可能作逆向運算。這也就是使用了兩個質數的所要達到的目的。 現在假設Alice和Bob分別是參與DH式金鑰交換過程的兩方,他們一開始會商議

神經網路的優化演算法選擇

博文內容轉載至:http://blog.csdn.net/ybdesire/article/details/51792925 優化演算法 解決優化問題,有很多演算法(最常見的就是梯度下降),這些演算法也可以用於優化神經網路。每個深度學習庫中,都包含了大量的優化演算法

NGINX之——配置HTTPS加密反向代理訪問–自簽CA

left https rac lan -s tar 一個 eight fcm 轉載請註明出處:http://blog.csdn.net/l1028386804/article/details/46695495 出於公司內部訪問考慮,採用的CA是本機Openssl

基於httpd建立私有CA實現https加密連接

ca https openssl 有關於https是什麽,點擊連接查看百度百科:https://baike.baidu.com/item/https/285356?fr=aladdin 一、準備工作 在開始實驗之前,我們要準備至少兩臺主機還有自身的計算機,一臺作為服務器,另外一臺作為

基於nginx建立CA實現https加密連接

nginx https openssl 前幾篇博客分別實現了nginx的http訪問和apache的https加密連接,那麽現在就將它們組合在一起,實現基於nginx的https加密連接。一、環境準備 這次我還是準備了兩個虛擬機和一臺真實計算機,其中一臺IP為172.16.128.7

HTTP要被拋棄? 亞洲誠信攜手寶塔開啟HTTPS加密快速通道

站點 電商 class 發現 justify 證書管理 生態 意義 text 推動全球網站的HTTPS化意義深遠,亞洲誠信與國內知名服務器控制面板廠商“寶塔”(www.bt.cn)達成戰略合作,攜手推出“SSL證書申請與管理”一站式自動化服務,讓寶塔用戶在申請SSL數

https加密 for ubuntu

com yam crontab 添加 update install upgrade code nta $sudo apt install software-properties-common $ sudo add-apt-repository ppa:certbot/cer

站長把網站https加密不僅安全還可以提高排名

網站 https 網站HTTPS化,將是以後的趨勢了。谷歌以前就推薦網站加密,最近谷歌瀏覽器更是把沒有SSL證書的網站標記為不安全。 谷歌再推HTTPS:Chrome瀏覽器將標記非HTTPS網站為不安全 不僅如此,以後谷歌搜索會把HTTPS的網站排名提升。 看來站長有必要把網站HTTPS一下了。現在H

mysql優化--in或者or選擇

mysql sql優化在數據庫查詢時,很多情況下會用到or或者in來過濾數據。這裏比較下這二者的效率,看看哪個更適合使用場景。測試平臺:centos7_x86_64 mysql-5.7.18 創建表,插入測試數據(1000萬條記錄)mysql> create table t_user (id in

https加密算法解析

個人 https rsa 公鑰 長度 算法 加密算 tps 應該 https加密算法: http層面通信接口通過ssl(安全套接字)或者tls(安全傳輸)來代替。(註釋:安全套接層 (SSL) 是一種協議,支持服務通過網絡進行通信而不損害安全性。它在客戶端和服務器之間創建一

https加密解密過程詳解

http col 驗證 獲取 安裝 因此 私鑰 請求 描述 在日常互聯網瀏覽網頁時,我們接觸到的大多都是 HTTP 協議,這種協議是未加密,即明文的。這使得 HTTP 協議在傳輸隱私數據時非常不安全。因此,用於對 HTTP 協議傳輸進行數據加密,即 HTTPS 。 那麽我們

Nginx安裝與升級 Nginx服務器 Nginx虛擬主機 、 HTTPS加密網站

fault 用戶 cli cipher pat 案例 fir 服務器 算法 案例1:搭建Nginx服務器案例2:用戶認證案例3:基於域名的虛擬主機案例4:SSL虛擬主機1 案例1:搭建Nginx服務器1.1 問題 在IP地址為192.168.4.5的主機上安裝部署Nginx

神經網絡優化算法如何選擇Adam,SGD

func lis 很多 base obs 分享圖片 .cn 得到 ttr 之前在tensorflow上和caffe上都折騰過CNN用來做視頻處理,在學習tensorflow例子的時候代碼裏面給的優化方案默認很多情況下都是直接用的AdamOptimizer優化算法,如下:

重要提醒:請做好網站HTTPS加密工作!

出現 googl 工作 淘寶 網站 上線 ssl證書 想想 互聯網 由於當前的互聯網環境越來越復雜,網絡安全隱患事件層出不窮,各主流網站也意識到HTTPS加密的重要性。一方面,淘寶、天貓、京東、百度等知名網站及時部署SSL證書。另一方面,像 Google、Mozilla等瀏