Encryption

如何在客戶端-伺服器應用程序中加密數據,以便只有客戶端可以讀取它?

  • December 13, 2016

要求

我們正在建構一個通過 RESTful API 連接多個客戶端的系統。它允許創建可信客戶端組。我們需要一種方法來儲存在伺服器端加密的組共享數據,只有該組中的客戶端才能解密。客戶應該能夠隨時加入該組,並且仍然可以訪問儲存的數據。

在更基本的描述中,讓我們假設:

  • Client1 和 Client2 屬於同一組。
  • Client1 想與 Client2 共享數據。為此,Client1 將加密數據保存在伺服器上,Client2 將獲取這些數據。
  • Client1 應該能夠理解數據。
  • Client2 應該能夠理解數據。
  • 伺服器不能理解數據
  • 當一個新客戶端(Client3)加入組時,他應該能夠理解數據。

解決方案

  • 一個組中的所有客戶端都有一對公鑰/私鑰。
  • 組中的所有客戶端都可以訪問組中所有其他客戶端的所有公鑰。
  • 每個組將有一個主密鑰“K”,用於加密/解密要與最初未設置的組共享的數據。

加入組的第一個客戶端(假設它是 Client1)將在本地創建和儲存 K,並將組標記為已初始化其主密鑰。然後它將使用 K 和 AES-128 加密的組共享數據發佈到 API。

當 Client2 加入該組時,將發生以下情況:

  • Client2 將檢查該組是否具有它所擁有的主密鑰 (K),因為它是由 Client1 創建的
  • Client2 將向任一組成員請求 K
  • Client1 將使用 Client2 的公鑰加密 K 並將其發送過來
  • Client2 將使用他的私鑰解密密鑰並將其儲存在本地,以便不再需要它
  • Client2 將從伺服器獲取加密數據並使用 K 對其進行解密(注意,Client2 不需要從伺服器獲取/儲存所有數據,只需要它感興趣的部分)

K 總是通過使用請求它的客戶端的公鑰對其進行加密來交換。這應該在客戶端首次加入組時最多發生 1 次。

問題

  1. 如果所有客戶端都離開了組(此時他們從本地儲存中刪除了 K),則伺服器上的所有資訊都將毫無用處,因為沒有人再擁有 K
  2. 如果 Client2 第一次上線,而另一個組成員不線上,它將無法獲得 K 並且將無法解密儲存在伺服器上的任何數據

當我看到這些問題時我是對的嗎?是否有解決方案來處理它們?

我不是這個領域的專家,所​​以你的建議會很有幫助。

  1. 如果所有客戶端都離開了組(此時他們從本地儲存中刪除了 K),則伺服器上的所有資訊都將毫無用處,因為沒有人再擁有 K

是的,這會發生,而且沒有辦法阻止它,除非你在系統中添加一些值得信賴的實例來儲存這些密鑰。

  1. 如果 Client2 第一次上線,而另一個組成員不線上,它將無法獲得 K 並且將無法解密儲存在伺服器上的任何數據

正確的。基本上這與第一個問題相同,其他問題只是暫時不可用而不是永久可用。

但是,您目前的解決方案有幾個方面需要討論:

  • 正如 cygnusv 在評論中指出的那樣:您沒有刪除使用者的機制。更改主密鑰是必要的,因為您無法強制刪除任何內容。
  • 用主密鑰加密文件……這很糟糕。特別是如果您必須交換主密鑰,這意味著您還必須再次解密和加密每個文件/數據庫。為每個文件、表等創建一個新密鑰,然後將其放入一個列表中,然後使用此列表。
  • 您有一個硬性要求,即伺服器必須不知道數據。您是否確保伺服器不會作為虛擬伺服器加入組(只是為了獲取密鑰)?因為您的訪問控制結構現在完全失去了。您也沒有說明誰處理權限、創建和發布密鑰等。
  • 邀請如何運作?組員會邀請嗎?誰發佈公鑰等……
  • 你想對數據做什麼?尤其是在數據庫中,這是一個問題,因為您無法處理加密數據。客戶端總是不得不從數據庫請求大量數據,在本地解密,然後在本地應用他們的操作,而不是發布 SQL 查詢。幾乎任何對此的優化都會向伺服器提供他不應該擁有的資訊。

您的方案確實意味著作為被動參與者的伺服器無法讀取數據,但如果您的威脅模型包括試圖訪問數據的伺服器,您將需要做更多的事情。tylo 提到了試圖加入組的伺服器(或其代理之一),但它也可能 MITM 另一個使用者加入組的過程(通過返回其控制下的公鑰)。

引用自:https://crypto.stackexchange.com/questions/22763