1. 程式人生 > >建立RSA協商加密的安全通道

建立RSA協商加密的安全通道

在基於TCP長連線的CS鏈路中,如何保證資料流的安全性是開發者最關注的問題之一。本文深入淺出的給大家介紹一下在TCP連線中,使用RSA協商加密的方式,建立一個安全加密的通訊鏈路,保證資料傳輸的安全性。文章分為3個主要部分,即RSA演算法簡介,安全通道協商流程詳解和一些工程優化方法。期望大家在讀了我這篇文章之後能夠透徹的理解基於RSA協商加密方式的通道建立方式並能夠運用在自己的業務實踐中。

RSA演算法簡介

加密演算法是計算機通訊安全的基石,加密演算法分為2個大類,即”對稱加密演算法“和”非對稱加密演算法“。”對稱加密演算法“的缺點比較明顯,即甲方必須把加密規則告訴乙方,否則無法解密。因此儲存和傳遞金鑰,就成了最頭疼的問題。本文所依賴的加密演算法RSA演算法是一種”非對稱加密演算法“,其具有以下特點:

  1. 乙方生成兩把金鑰(公鑰和私鑰)。公鑰是公開的,任何人都可以獲得,私鑰則是保密的
  2. 甲方獲取乙方的公鑰,然後用它對資訊加密。
  3. 乙方得到加密後的資訊,用私鑰解密。

安全通道協商流程

我們選擇使用RSA加密演算法建立安全通道,在介紹具體方法之前,我們先約定幾個術語:

  • C表示客戶端(Client)
  • S表示服務端(Server)
  • priKey表示私鑰(PrivateKey)
  • pubKey表示公鑰(PublicKey)

下面分步驟對流程進行詳細描述。

前提說明

在安全通道建立之前,客戶端和服務端已經擁有一套公私鑰對,公鑰由客戶端持有,私鑰由服務端持有。這裡的公私鑰分別表示為:pubKey0和priKey0

.

C->S傳遞pubKey

  1. 客戶端生成一對公私鑰,分別表示為pubKeyC和priKeyC,其中priKeyC客戶端自己持有,pubKeyC需要傳遞給服務端;
  2. 客戶端使用pubKey0對pubKeyC進行加密,然後通過TCP鏈路將加密後的資料傳輸給服務端;(這個過程我們稱為Stage1)
  3. 服務端收到客戶端加密的資訊後,使用priKey0對資訊進行解密,得到pubKeyC.

S->C傳遞pubKey

  1. 服務端生成一對公私鑰,分別表示為pubKeyS和priKeyS,其中priKeyS服務端自己持有,pubKeyS需要傳遞給客戶端;
  2. 服務端使用pubKeyC對pubKeyS進行加密,然後通過TCP鏈路將加密後的資料傳輸給客戶端;(這個過程我們稱為Stage3)
  3. 客戶端收到服務端加密的資訊後,使用priKeyC對資訊進行解密,得到pubKeyS.

加密通訊

經過上述全雙工的加密協商過程,客戶端和服務端之間就建立了使用RSA演算法進行加密的通訊通道,後續的資料傳輸就是在上述安全通道下進行的。具體如下:

  1. C-->S的資料,在C端加密,在S端解密,使用的是由客戶端初始化生成的公私鑰對(priKeyC和pubKeyC);
  2. S-->C的資料,在S端加密,在C端解密,使用的是由服務端初始化生成的公私鑰對(priKeyS和pubKeyS).

工程實踐中的一些優化點

儘量降低初始化私鑰priKey0洩漏風險

上述公私鑰協商過程的安全性是建立在初始化私鑰,即服務端所持有的priKey0未洩漏的基礎上的。如果priKey0洩漏了,那麼理論上這個”安全“通道就不安全了。一般工程實踐中,會通過2中方式去儘量降低私鑰洩漏風險:

  • 將初始化公私鑰對從一對擴充套件到多對,在Stage1的過程中,選擇某一個公鑰對資料進行加密,同時將公鑰索引追加到傳遞給服務端的資訊中去。服務端在收到資訊後先解析出索引,然後取出對應的私鑰進行解密;
  • 不定期的更新公私鑰對,這種方案會有一定的弊端,服務端需要同時維護針對不同客戶端版本的私鑰資訊,並且還要額外增加一個欄位標識服務端使用那對私鑰進行解密,不過可以通過控制客戶端版本數量的方式,將維護成本降低,如維護2個版本客戶端,其他版本強制退出。

服務端Stage3初始化公私鑰效能

對於客戶端來說,每次建立安全通道,單個客戶端只需要進行一次公私鑰對的初始化計算,效能不是瓶頸。但是,對於服務端來說,尤其是接入層,服務了眾多TCP長連線,如果頻繁的進行公私鑰對的初始化計算,CPU效能的消耗成本是巨大的。所以一般工程實踐中,會選擇一種更為理性的方案。 具體做法可以是:

  1. 在服務端啟動的時候,預先初始化多對公私鑰對,如可以初始化128對或者更多,然後將這些公私鑰對儲存在記憶體中。
  2. 在Stage3截斷,服務端不即時生成公私鑰對,只需要隨機選擇一個記憶體中的一對公私鑰,並進行加密操作,將對於的公鑰傳遞給客戶端即可。

以上,就是本文的所有內容,期望大家看了之後能有所收穫,謝謝大家!