最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

即時通訊安全篇(十一):IM聊天系統(tǒng)安全手段之傳輸內容端到端加密技術

2022-08-29 16:33 作者:nickkckckck  | 我要投稿

本文由融云技術團隊分享,原題“互聯網通信安全之端到端加密技術”,內容有較多修訂和改動。

1、引言

在上篇《IM聊天系統(tǒng)安全手段之通信連接層加密技術》中,分享了關于通信連接層加密的相關技術和實踐,包括在傳輸即時通信消息時啟用 TLS 鏈路加密(保證消息在到達服務器前無法被竊聽和篡改)、使用 CA 認證機制(杜絕中間人攻擊)等。

本篇將圍繞IM傳輸內容的安全問題,以實踐為基礎,為你分享即時通訊應用中的“端到端”加密技術。

學習交流:

- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》

- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點此)

(本文已同步發(fā)布于:http://www.52im.net/thread-4026-1-1.html)

2、系列文章

本文是IM通訊安全知識系列文章中的第11篇,此系列總目錄如下:

  • 《即時通訊安全篇(一):正確地理解和使用Android端加密算法》

  • 《即時通訊安全篇(二):探討組合加密算法在IM中的應用》

  • 《即時通訊安全篇(三):常用加解密算法與通訊安全講解》

  • 《即時通訊安全篇(四):實例分析Android中密鑰硬編碼的風險》

  • 《即時通訊安全篇(五):對稱加密技術在Android平臺上的應用實踐》

  • 《即時通訊安全篇(六):非對稱加密技術的原理與應用實踐》

  • 《即時通訊安全篇(七):如果這樣來理解HTTPS原理,一篇就夠了》

  • 《即時通訊安全篇(八):你知道,HTTPS用的是對稱加密還是非對稱加密?》

  • 《即時通訊安全篇(九):為什么要用HTTPS?深入淺出,探密短連接的安全性》

  • 《即時通訊安全篇(十):IM聊天系統(tǒng)安全手段之通信連接層加密技術》

  • 《即時通訊安全篇(十一):IM聊天系統(tǒng)安全手段之傳輸內容端到端加密技術》(* 本文

3、為什么需要端到端加密?

上篇中提到的連接層加密技術,這是提升IM客戶端到服務器之間數據傳輸的安全性手段,但是這并不能解決用戶間的通信隱私性以及安全性風險。

因為在將數據傳輸到服務器之后,所有有權訪問此服務器的人,包括員工、供應商及其他有關人員(甚至黑客),都有可能讀取到用戶的數據。

有鑒于此,端到端加密技術在即時通訊IM領域被廣泛應用,包括WhatsApp、Signal、Telegram 等國外即時通信軟件中都有使用。

PS:有關端到端加密的基礎知識,可以從這兩篇里得到,建議詳讀:

  • 《移動端安全通信的利器——端到端加密(E2EE)技術詳解》

  • 《簡述實時音視頻聊天中端到端加密(E2EE)的工作原理》

4、端到端加密的技術設計思路

4.1 簡化版思路

說到端到端加密,我們首先想到的解決方案是:在發(fā)送端發(fā)送消息前對整個消息進行加密,接收端接收到消息后進行解密。

如上這樣:消息中轉服務器就無法獲取我們的消息內容了。

事實上:這確實是端到端加密中消息收發(fā)的簡化版解決方案,只是我們在實際應用中要更加復雜,效果也更加安全。

4.2 如何安全地傳遞用于消息加解密的密鑰

對于端到端加密,我們需要先解決的前置安全問題是:如何安全地傳遞用于消息加解密的密鑰。

答案是:用非對稱加密的方式傳輸密鑰(與 SSL / TLS 中安全交換密鑰的方式類似)。

非對稱加密傳輸對稱加密密鑰的算法,一般歸結兩種方式:

  • 1)一種是以 RSA、ECC 等為主(公鑰加密私鑰解密的方式,本質是加解密的算法);

  • 2)另一種是以 DH、ECDH 為主的生成共享密鑰的方式(本質是通過計算協商一個共同的密鑰而不是加解密算法)。

實際上:大部分即時通信軟件中的端到端加密都采用生成共享密鑰的方式來傳輸會話密鑰。這是為什么呢?

這就涉及到 DH 算法(即 Diffie-Hellman 密鑰交換算法),關于DH算法的資料,有興趣可以詳讀《Diffie-Hellman密鑰協商算法》,限于篇幅,這里不專門討論。

Diffie-Hellman 密鑰交換算法的安全性依賴于這樣一個事實:雖然計算以一個素數為模的指數相對容易,但計算離散對數卻很困難。對于大的素數,計算出離散對數幾乎是不可能的。

這里簡要描述一下 DH 共享密鑰的過程如下:

(其中“密鑰 S”即為最終的共享密鑰)

4.3 采用共享密鑰的原因

端到端加密采用共享密鑰的方式來傳輸會話密鑰有如下幾個原因:

1)如果采用 RSA、ECC 等公鑰加密私鑰解密的方式傳輸密鑰,需要在創(chuàng)建會話時生成臨時密鑰,并通過對方公鑰加密后傳輸到接收端。

這就需要完全保證消息的可靠性,如果該消息在任何一個環(huán)節(jié)中丟失或損壞,則后續(xù)通信都無法進行?;蛘?,需要采用更為可靠的傳輸方案,通常做法為需要接收端在線,通過各種確認來保證這個可靠性。

而采用共享密鑰的方式則只需要知道對方的公鑰,就可以完成生成共享密鑰,并不一定需要對方在線。

2)如果已經生成的臨時對稱密鑰丟失,則需要重新協商密鑰。而采用共享密鑰的方式則只需要知道對方的公鑰,就可以完成生成共享密鑰,不需要重新協商。

3)采用公鑰加密私鑰解密的方式至少會比生成共享密鑰方式多一次交換對稱密鑰的通信過程。

4)密鑰協商方式,不僅僅可以完成兩個點之間的密鑰協商,還可以延展到多人之間的共同協商出相同的密鑰,這樣能滿足多人群體溝通的需求。

5、端到端加密的初步實踐方案

我們結合對于 DH 算法(即 Diffie-Hellman 密鑰交換算法)這種共享密鑰方式的認知(即公鑰可隨意公開),先設計一個簡單的端到端消息加密的過程。

這個過程的邏輯流程如下:

  • 1)在客戶端 APP 首次安裝時,基于服務器公開的兩個全局的參數,生成自己的 DH 公鑰和私鑰;

  • 2)將自己的公鑰上傳證書服務器,證書服務器上保存用戶標識與其公鑰的關系。私鑰則保存在客戶端上;

  • 3)首次給對方發(fā)送消息或首次接收到對方消息時,便到證書服務器查詢對方的公鑰;

  • 4)根據對方公鑰和自己的私鑰計算出共享密鑰;

  • 5)后續(xù)與對方所有的消息都基于這個密鑰和相同的對稱加解密算法進行加密解密操作。

端到端消息加密過程示意:

至此:我們完成了一個簡單的端到端消息加密方案,在這個方案中我們引入了一個第三方的用于存儲用戶公鑰的角色,這個角色的存在可以讓任何一方都不用關心對方的在線狀態(tài),隨時給對方發(fā)送加密過消息,而消息轉發(fā)服務器無法解密消息。

接下來,我們針對這個簡單方案存在的各種安全隱患問題,進行逐步分析和優(yōu)化。

6、端到端加密實踐方案的進一步優(yōu)化和演進

6.1 使用HMAC作為消息完整性認證算法

在消息傳輸過程中,雙方需要確認彼此消息的完整性,簡單的做法就是將消息進行 Hash,得到的 Hash 值附加到消息后,隨消息一起發(fā)送;對端接收后,同樣進行 Hash,來驗證消息是否被篡改。

關鍵點在于不同數據得到的 Hash 值一定不同,其中帶密鑰的 Hash 值就是 MAC算法。

另外,為了避免使用同樣的 Hash 函數對相同數據進行操作總是得出同樣的值,額外加入一個密鑰,這樣使用不同密鑰就可以得出不同的 MAC。當然,這個密鑰是兩個對端都知道的。

這樣,我們就得到了基于加密 Hash 的消息完整性認證的算法——Hash-based MAC(簡稱HMAC)。

基礎知識1:什么是MAC算法?

全稱Message Authentication Code,即消息認證碼(帶密鑰的Hash函數)。在密碼學中,MAC是通信實體雙方使用的一種驗證機制,是保證消息數據完整性的一種工具。

MAC算法的安全性依賴于Hash函數,故也稱帶密鑰的Hash函數。消息認證碼是基于密鑰和消息摘要“hash”所獲得的一個值,可用于數據源發(fā)認證和完整性校驗。

使用 MAC 驗證消息完整性的具體過程是:

  • 1)假設通信雙方 A 和 B 共享密鑰 K,A用消息認證碼算法將 K 和消息 M 計算出消息驗證碼 Mac,然后將 Mac 和 M 一起發(fā)送給 B;

  • 2)B 接收到 Mac 和 M 后,利用 M 和 K 計算出新的驗證碼 Mac*,若 Mac*和Mac 相等則驗證成功,證明消息未被篡改。

由于攻擊者沒有密鑰 K,攻擊者修改了消息內容后無法計算出相應的消息驗證碼,因此 B 就能夠發(fā)現消息完整性遭到破壞。

簡而言之就是:

  • 1)發(fā)送者通過MAC算法計算出消息的MAC值,并和消息一起發(fā)給收信者;

  • 2)收信者用同樣的MAC算法計算收到的消息的MAC值,并對比兩者。

下圖是原理示意:

基礎知識2:什么是HMAC算法?

HMAC是MAC算法中的一種,其基于加密HASH算法實現。任何加密HASH, 比如MD5、SHA256等,都可以用來實現HMAC算法,其相應的算法稱為HMAC-MD5、HMAC-SHA256等。

6.2 使用ECDH算法替換DH算法

DH 算法是以離散對數的數學難題為基礎的,隨著計算機計算能力逐步增強,我們要不停地使用更大的數以增加破解難度,目前業(yè)界普遍認為至少需要使用 2048 位 DH 算法才具備更好的安全性。

在此我們引入 ECDH 算法替換 DH 算法。ECDH 密鑰協商算法是 ECC 算法和 DH 密鑰交換原理結合使用。ECC 是建立在基于橢圓曲線的離散對數問題上的密碼體制。在相同破解難度下,ECC 具有更小長度的密鑰和更快的正向計算速度優(yōu)勢。

我們系統(tǒng)上的 ECDH 可以直接采用目前公開的 sepc256kl 和 Curve25519 曲線,而無需服務再提供公開大數參數。

6.3 提升前向安全性

在消息傳輸過程中,如果協商好的密鑰泄露了,就意味著所有信息都將暴露于風險之下。

為了防止這種情況發(fā)生,我們需要每次加密使用的密鑰都與上一次不同,且不可以反向推導得出之前的密鑰。

此處引入一個 Hash 算法:這個 Hash 算法可以通過輸入一個密鑰導出另外一個離散性更大的密鑰,每次發(fā)送消息時都是用上次的消息密鑰進行 Hash 運算得出本次密鑰,由于 Hash 算法具有單向不可逆的特性,因此就無法通過本次的密鑰推導之前的密鑰。

從感觀上,這就像一個棘輪,棘輪就是一種特殊的齒輪,他只能往一個方向轉下去,而不能往回轉。

我們先來感性認識一下棘輪:

在技術上,做到"只能往一個方向轉下去,而不能往回轉",是達到前向安全的關鍵。這就保證了,如果某一輪的密鑰被破解出來,但前面的密鑰是無法計算出來的,也就是前面的消息無法被解密。

6.4 同時保證前向安全和后向安全性

出于極致的安全性要求,我們會同時考慮前向安全和后向安全。如何保證在某次通信中,被破解出來的密鑰,不能破解出之前的消息,而且在一定周期內,這個破解出來的密鑰將不會再起作用。

介于此我們再引入另外一個棘輪來保證其向后的安全性。這就是大名鼎鼎的?Signal protocol?中的雙棘輪算法。

Signal protocol 是真正的端到端的通訊加密協議,號稱是世界上最安全的通訊協議,任何第三方包括服務器都無法查看通訊內容。

雙棘輪算法包含一個 KDF 棘輪和一個 DH 棘輪。

KDF 全稱(Key derivation function) 密鑰導出函數,用于從一個原始的密鑰導出一個或多個密鑰。本質上就是 Hash 函數,通常用來將短密碼變成長密碼。另外 KDF 需要加“鹽”(salt),用于防彩虹表,出于 Hash 的特性,這個“鹽”的長度至少要大于 Hash 結果長度。

KDF (原密鑰,鹽) = 導出密鑰

KDF 棘輪就是運用 KDF 算法,設計出一種密鑰不斷變化的效果,流程如下:

首先:將初始密鑰使用 KDF 算法導出新的密鑰,新密鑰被切成兩部分,前半部分作為下一次 KDF 計算的輸入,后半部分作為消息密鑰。

每迭代一次(也可以說棘輪步進一次),就會生成新的消息密鑰。

由于 KDF 算法的單向性,通過這條消息的密鑰無法倒推出上一條消息密鑰,這就保證了密鑰的前向安全。但是如果 KDF 中的鹽被掌握,那么它就可以按照這種算法計算出以后所有的消息密鑰。

為了保證后向安全,就要設計一種方法,使每次迭代時引入的鹽是隨機的,從而保證每次的消息密鑰是不可以向后推算的。

由前面介紹的 DH 算法得知:兩對密鑰對可以通過 DH 協議生成一個安全的協商密鑰,如果更換其中一個密鑰對,新的協商密鑰也會變化。

根據這個方法:我們可以設計出一個安全更新鹽的方法。我們在證書服務器增加一個臨時公鑰證書,這個臨時證書是按照接收雙方標識構建的臨時公鑰對,即每個人的每個單人會話都具備一個臨時公鑰。每進行一個消息輪回,就更新一次己方的臨時公鑰,同時根據另外一方的臨時公鑰和己方的私鑰進行協商,并將協商出的密鑰作為鹽,使得 KDF 棘輪算法生成的消息密鑰具有后向安全性。

在初始時我們無法預測出每個人所有的新二人會話:那么我們就可以規(guī)定創(chuàng)建新的二人會話時,發(fā)起方首先生成一個新的臨時 DH 公私鑰對,并向服務器上傳自己的臨時 DH 公鑰;其次發(fā)送方用接收方公布的長期公鑰與自己的臨時私鑰協商出密鑰作為消息加密的密鑰,對消息進行加密;最后接收方首次接收到消息后用自己的長期公鑰和發(fā)送方的臨時私鑰計算得出消息密鑰,并在首次回復消息時生成臨時公私鑰,同時上傳臨時公鑰。

問題是:如果接收端不在線,而發(fā)送端每條消息都去更新己方的臨時公鑰證書,就會導致發(fā)出去的這些消息,在接收端上線并收取后無法被正常解密。

為了解決這個問題,我們需要規(guī)定:只有在發(fā)出消息并得到對方回復后才更新臨時證書,若對方不回復消息則不去更新臨時證書。接收端能回復消息就表示其已經上線并接收完消息,這樣就可以保證離線消息或者消息亂序也可以被對方正常解析。這種方法就是雙棘輪算法中的另外一個 DH 棘輪。

6.5 更安全的密鑰交換協議—— X3DH

對比最初的方案,為了滿足消息的前向安全和后向安全,我們增加了雙棘輪算法,在原基礎方案上為每個人增加了一組會話級別臨時 DH 密鑰,每個人都擁有一個長期密鑰和一組臨時密鑰。

但是:由于長期密鑰無法被更換,所以方案依然存在著安全隱患。

因此:Signal protocol 設計了一種更為復雜和安全的 DH 密鑰交換過程,稱之為?X3DH(即 DH 協議的 3 倍擴展版)。

在 X3DH 協議里,每個人都要創(chuàng)建 3 種密鑰對,分別如下:

  • 1)身份密鑰對(Identity Key Pair):一個長期的符合 DH 協議的密鑰對,用戶注冊時創(chuàng)建,與用戶身份綁定;

  • 2)已簽名的預共享密鑰(Signed Pre Key):一個中期的符合 DH 協議的密鑰對,用戶注冊時創(chuàng)建,由身份密鑰簽名,并定期進行輪換,此密鑰可能是為了保護身份密鑰不被泄露;

  • 3)一次性預共享密鑰(One-Time Pre Keys):一次性使用的?Curve25519?密鑰對隊列,安裝時生成,不足時補充。

所有人都要將這 3 種密鑰對的公鑰上傳到服務器上,以便其他人發(fā)起會話時使用。

假如 Alice 要給 Bob 發(fā)送消息,首先要和 Bob 確定消息密鑰,流程大致如下:

  • 1)Alice 要創(chuàng)建一個臨時密鑰對(ephemeral key),我們設成 EPK-A,此密鑰對是為了后面棘輪算法準備,在此處作用不大;

  • 2)Alice 從服務器獲取 Bob 的三種密鑰對的公鑰:身份密鑰對IPK-B、已簽名的預共享密鑰 SPK-B、一次性預共享密鑰 OPK-B;

  • 3)Alice 開始使用 DH 協議計算協商密鑰,要引入參數包括:自己創(chuàng)建的兩個密鑰對的私鑰,以及 Bob 的三個公鑰。然后用類似排列組合的方式,將自己的私鑰與對方的公鑰分別帶入 DH 算法計算。

DH1 = DH(IPK-A, SPK-B)

DH2 = DH(EPK-A, IPK-B)

DH3 = DH(EPK-A, SPK-B)

DH4 = DH(IPK-A, OPK-B)

如圖所示:

然后將計算得到的四個值,前后連接起來,就得到了初始密鑰,如下:

DH = DH1 || DH2 || DH3 || DH4

注:“||”代表連接符,比如 456 || 123 = 456123

但是 DH 這個密鑰太長,不適合作為消息密鑰,所以對這個初始密鑰進行一次 KDF 計算,以衍生出固定長度的消息密鑰 S:

S = KDF(DH1 || DH2 || DH3 || DH4)

這一步,Alice 終于計算出了消息密鑰 S。

于是:

  • 1)Alice 使用消息密鑰 S 對消息進行加密,連同自己的身份公鑰 IPK-A 和臨時公鑰 EPK-A 一同發(fā)給 Bob;

  • 2)Bob 收到 Alice 的信息后,取出 Alice 的 2 個公鑰,連同自己的密鑰,使用與 Alice 相同的算法計算消息密鑰 S;

  • 3)Bob 和 Alice 使用消息密鑰進行加密通訊。

由上可知:X3DH 實際是復雜版的 DH 協議。

至此:我們簡單介紹了 Signal Protocol 中最為核心的 X3DH 協議與雙棘輪算法,基本上可以滿足前向安全和后向安全。當然,真實的處理過程會更為復雜和安全。

7、IM群聊的端到端加密方案

在即時通訊場景中,除了二人之間的聊天以外,還有一個重要的場景就是群聊,那么群聊時的多人消息如何做端到端加密呢?

我們再次回到 DH 密鑰協商算法上的推導過程:顯然,多方情況下依然可以繼續(xù)使用 DH 密鑰協商算法,這就是群聊中端到端加密的基礎。

而 Signal Protocol 在群組聊天中的設計與二人聊天又有所不同,由于群聊的保密性要求相對低一些,只采用了 KDF 鏈棘輪+公鑰簽名來進行加密通訊以保障加密的前向安全。

群組聊天的加解密通訊流程如下:

  • 1)每個群組成員都要首先生成隨機 32 字節(jié)的 KDF 鏈密鑰(Chain Key),用于生成消息密鑰,以保障消息密鑰的前向安全性,同時還要生成一個隨機 Curve25519 簽名密鑰對,用于消息簽名;

  • 2)每個群組成員用向其它成員單獨加密發(fā)送鏈密鑰(Chain Key)和簽名公鑰。此時每一個成員都擁有群內所有成員的鏈密鑰和簽名公鑰;

  • 3)當一名成員發(fā)送消息時,首先用 KDF 鏈棘輪算法生成的消息密鑰加密消息,然后使用私鑰簽名,再將消息發(fā)給服務器,由服務器發(fā)送給其它成員;

  • 4)其它成員收到加密消息后,首先使用發(fā)送人的簽名公鑰驗證,驗證成功后,使用相應的鏈密鑰生成消息密鑰,并用消息密鑰解密;

  • 5)當群組成員離開時,所有的群組成員都清除自己鏈密鑰和簽名公鑰并重新生成,再次單獨發(fā)給每一位成員。這樣操作,離開的成員就無法查看群組內的消息了。

由上可知:一個人在不同的群組里,會生成不同的鏈密鑰和簽名密鑰對,以保障群組之間的隔離。在每個群組中,每個成員還要存儲其它成員的 KDF 鏈和簽名公鑰,如果群組成員過多,加解密運算量非常大,會影響發(fā)送和接收速度,同時密鑰管理數據庫也會非常大,讀取效率也會降低。

所以:群組聊天使用?Signal Protocol 協議,群人數不宜太多。

8、端到端加密方案的補充說明

上面我們介紹了即時通信中二人聊天和群組聊天的端到端加密全部過程。但是正常情況下端到端消息加密只是加密消息的實際負載部分(即只加密消息“體”部分),而消息的控制層則不會被加密,因為消息轉發(fā)服務器需要根據控制信息進行消息轉發(fā)或路由(否則肯定大大影響IM底層的路由和通信效率,因為需要反復加密解密)。

為了防止消息被定向分析(分析用戶什么時間向誰發(fā)送了消息,或接收了誰的消息),我們依然需要對整體即時通信的長連接鏈路進行加密保護(這說的就是上篇文章里的通信連接層加密技術了),防止信息被中間網絡設備截獲并分析。而且為了防止密鑰服務器被中間人攻擊,也需要開啟鏈路加密保護。

9、參考資料

[1]?移動端安全通信的利器——端到端加密(E2EE)技術詳解

[2]?簡述實時音視頻聊天中端到端加密(E2EE)的工作原理

[3]?HASH、MAC、HMAC學習

[4]?一文了解加解密、哈希函數、MAC、數字簽名、證書、CA等

[5]?雙棘輪算法:端對端加密安全協議,原理以及流程詳解

[6]?Signal protocol 開源協議理解

[7]?X25519(Curve25519)橢圓曲線參考資料

(本文已同步發(fā)布于:http://www.52im.net/thread-4026-1-1.html)


即時通訊安全篇(十一):IM聊天系統(tǒng)安全手段之傳輸內容端到端加密技術的評論 (共 條)

分享到微博請遵守國家法律
宽甸| 罗甸县| 利川市| 弋阳县| 固阳县| 峨山| 都江堰市| 浪卡子县| 松阳县| 哈巴河县| 内丘县| 绥阳县| 阳东县| 宁波市| 邳州市| 西峡县| 辽宁省| 荣成市| 横峰县| 卢氏县| 诏安县| 柳河县| 平舆县| 清徐县| 云浮市| 内乡县| 桃源县| 南平市| 周口市| 酒泉市| 出国| 慈利县| 莱州市| 宝清县| 天水市| 定南县| 巩留县| 电白县| 福安市| 陆丰市| 蒙阴县|