使用非對稱加密代表第三方對連續數據流進行安全有效的加密
我想設計一個基於 API 的系統,該系統能夠安全地加密代表外部使用者接收的數據流,從而只能使用只有使用者知道的秘密(即加密後數據,伺服器本身將無法再次解密)。自然,我的第一個想法是為此使用非對稱加密:
- 伺服器將生成一個私鑰/公鑰對(例如使用 RSA)
- 私鑰將安全地交給使用者並從伺服器中刪除,公鑰將儲存在伺服器上。
- 當新數據到達使用者時,伺服器會為對稱加密方案(例如 AES)生成一個隨機密鑰,並使用該密鑰對數據進行加密。然後它將使用使用者公鑰加密對稱密鑰並將其與數據一起儲存在伺服器上。
- 然後,使用者可以通過使用相應的加密對稱密鑰下載加密數據,使用他/她的私鑰解密對稱密鑰,最後使用解密的對稱密鑰解密數據來解密數據。
主要挑戰是代表使用者接收的數據由許多隨時間連續到達的小包組成。為了按照這種方案對它們進行加密,因此每次新數據包到達時都需要生成和加密一個新的對稱密鑰,這是可行的。但是,數據的解密可能會變得非常低效,因為在現代硬體上解密 RSA-2048 加密消息可能需要幾毫秒,因此如果單個使用者有數千甚至數百萬條消息,他們的解密可能需要小時。
因此,我有兩個問題:
- 這是一個合理的方案嗎?如果現在,缺少哪些元素或建議另外實施哪些元素(HMAC、簽名、…)?
- 有什麼方法可以提高解密過程的效率,最好是不涉及在伺服器上長時間儲存對稱密鑰的方法(這會帶來安全風險)?
編輯
使用者不上傳數據,由第三方代表使用者生成。該方案背後的動機是為第三方提供一個安全的非同步通道來儲存使用者可以在以後安全獲取的數據。假設第三方自己不能或不願意為此提供基礎設施,而是想使用外部服務。
讓我們從僅在評論中最重要的部分開始,我們要防範的內容:
加密數據的主要動機是防止數據被盜或意外洩漏,並降低服務提供商的風險。
意外洩漏並不是真正的威脅,因為我們不能停止洩漏目前數據,除非有人告訴它,否則您的伺服器不會解密。所以讓我們主要考慮盜竊,讓我們嘗試優化使用者解密,而不是加密(但這可能是我們接下來要做的事情)。
有什麼方法可以提高解密過程的效率,最好是不涉及在伺服器上長時間儲存對稱密鑰的方法(這會帶來安全風險)?
假設您的伺服器被黑客入侵。您將如何準確確定感染時間?5 分鐘的關鍵生命週期真的會受到傷害嗎?我會說不,所以讓我們假設這是我們希望我們的數據不加密的最長時間。
此外,我們在這裡不專注於選擇算法,所以讓我們假設 RSA、AES 和通用 KDF。
我會隨身攜帶一些東西:
- 我們從您的算法開始,只需使用 RSA 加密密鑰 K1 並將其儲存在某處
- 使用 KDF 將 K1 拆分為兩個:K1A 和 K1B
- 使用密鑰 K1A 加密消息(您可能希望在這裡使用 HMAC 或 AEAD 方案,我們不希望受損/有故障的伺服器提供隨機數據)。一鍵保存多少消息取決於您(我認為 5 分鐘很好,但可以根據自己的喜好進行配置)。
- 生成新密鑰 K2 並保存:K1B xor K2。
- 忘記 K1、K1A、K1B 並使 K1:=K2。
- 等待下一個要加密的數據包到達。您可以隨時忘記密鑰並從全新的密鑰開始(以不對稱操作為代價)
這使攻擊者能夠在任何時候破壞伺服器並且從未完全更改 K1 時查看新數據。這並不算太糟糕,因為您可以強制執行定期更改,如果伺服器受到破壞,那麼無論如何都會失去所有內容。
至於性能,它在任何一方都沒有提供完美的並行化。但是多個伺服器可以同時對多個鍵進行操作(如果數據將被標記為使用哪個鍵)。對於使用者來說,這為每個 RSA 束提供了並行化(如果有足夠的核心,您可以一次解密所有束)。在束內部,我們只使用對稱加密,但沒有消息之間的並行化。因此,理論上這可以每天或每月僅使用 1 個新的 RSA 安全密鑰,而不會損害後面的安全性,僅向前(以並行化為代價)。
這是一個合理的方案嗎?如果現在,缺少哪些元素或建議另外實施哪些元素(HMAC、簽名、…)?
HMAC 或 AEAD 總是很好而且不太貴。我看不出在這裡簽名的理由。但是您可能想聘請某人來幫助您,因為安全並不是一件容易的事。
私鑰將安全地交給使用者並從伺服器中刪除,公鑰將儲存在伺服器上。
請不要。忽略“安全處理”,這會帶來不必要的風險。