如何加密永遠不會離開客戶端但沒有伺服器就無法解密的數據?
條款:
客戶端:使用 JavaScript、HTML、CSS 編寫並與 Capacitor / Tauri 打包的瀏覽器、移動應用程序或桌面應用程序。
伺服器:基於 NodeJS 的 API。
數據:使用者名/密碼
供應商:第三方集成
背景:
我正在編寫與各種供應商的集成,要求使用者輸入他們的供應商數據,以便我們的自動化流程登錄並執行他們的任務。為了客戶的安全意識,我們不會將數據儲存在伺服器上(加密或其他方式)。處理是在客戶端完成的,反過來,伺服器不需要訪問數據。
問題:
我想以這樣一種方式加密這些數據,即只有在使用者登錄並與伺服器建立連接時才能對其進行解密。
我的解決方案:
想法1:密鑰儲存在伺服器上
- 使用者添加供應商集成
- 伺服器生成特定於該供應商的“密鑰”,將其保存在用於該集成的數據庫中並將其返回給客戶端
- 客戶端加密數據並儲存。
- 當需要進行同步時(僅當使用者登錄我的平台時才會發生),我們請求供應商密鑰並解密數據並僅在記憶體中使用它。
想法 2:非對稱加密
- 使用者添加供應商集成
- 伺服器生成一個公鑰/私鑰,將私鑰與使用者供應商集成儲存在數據庫中,並將公鑰返回給客戶端。使用者只要登錄就可以使用公鑰。
- 然後客戶端使用公鑰加密數據
- 當需要同步時,我們將加密數據發送到伺服器,伺服器返回一個解密版本供我們僅在記憶體中使用。
問題:
據我了解,Idea 1 對我來說似乎是安全且可取的,因為使用者數據永遠不會離開設備,即使被解密。想法 2 看起來很安全,但我想不出比在想法 1 中使用儲存密鑰方法有什麼好處。
我的理解是否正確,還是應該使用其他方法來安全地加密這些數據?
在加密之前或在伺服器允許客戶端解密之後,客戶端將擁有對任何未加密數據的完全訪問權限。
這意味著您需要信任客戶端不會導出未加密的數據。完全鎖定設備是不可能的——例如,有人可以簡單地將攝影機對准他們的顯示器以“導出”未加密的數據。但是,您可以採取措施使使用者難以在設備上安裝自己的提取軟體。
您需要做的就是在伺服器上儲存每個供應商的密鑰,保留一個只有客戶端知道的不同的每個供應商的密鑰,然後將它們結合起來以獲得實際的加密/解密密鑰。您可以簡單地對它們進行異或運算以派生密鑰。
現在,當需要訪問數據時,客戶端登錄到伺服器並請求伺服器密鑰的副本,並通過將伺服器密鑰與客戶端密鑰組合來解密內容。
如果您想要更細粒度,您可以為每個儲存的數據單元擁有一個客戶端和伺服器密鑰。因此,伺服器可以記錄對特定供應商的不同數據單元的訪問,因此可以限制客戶端請求訪問的速率。現在,客戶端將不得不根據需要訪問的數據向伺服器請求多個密鑰。客戶端可以使用 HKDF 生成多個單位客戶端密鑰,但伺服器密鑰應獨立生成,以便客戶端必須為每個需要解密的單元請求每個伺服器密鑰。
由於必須信任客戶端,因此客戶端可以在完成對修改後的供應商數據的解密/重新加密後立即丟棄伺服器的密鑰和派生的加密/解密密鑰。您可能會讓客戶端軟體在一段時間後自動超時,並要求客戶端重新登錄伺服器以繼續處理供應商數據。
請注意,這實際上是一種秘密共享方法,可以擴展到需要多方的幫助。您可以使用Shamir 的秘密共享來要求一定門檻值的各方授予對客戶端數據的訪問權限。