祕密是什麼,該如何在 JAVA 中處理祕密

已完成

祕密是不該與外部世界共用的字元字串:可能是資料庫密碼、私密金鑰、個人存取權杖等等。 為增強安全性,許多人也認為凡能對攻擊者提供幫助的內容皆應視為祕密:例如,生產資料庫的 URL 可視為祕密。 您的資料庫不應提供公開存取。 理由是這類資訊本質上即具敏感性,而且程式碼提供的資訊愈少愈好。

零信任和零祕密是什麼?

零信任的概念是不應該盲目信任任何人,而且所有人都需要經過驗證和授權才能存取公司資源。

此概念也適用於 Web 應用程式:應用程式不該將祕密儲存在程式碼或最終二進位檔中。 這就是所謂的零祕密。

秘密應該由外部系統管理,並具有嚴格的存取規則和驗證,以減少攻擊風險。

請不要將祕密放在 Git 存放庫

即使您的 Git 存放庫是私人的,在原始程式碼中放置任何祕密都是不正確的做法:

  • 任何有權存取您存放庫的人都會知道敏感數據
  • 具有應用程式二進位檔存取權的任何人都可以從中擷取秘密

此外,一旦秘密儲存在 Git 存放庫中,攻擊者一律可以藉由查看存放庫的歷程記錄來尋找它,在經過很長一段時間之後就可以忘記它。

即使這樣做似乎很實用,您也不應該將任何秘密儲存在原始程式碼存放庫中。 若要避免此問題,您可以使用自動工具來定期檢查您的存放庫,並在發現錯誤儲存的密碼或資料庫 URL 時傳送警告。

使用環境變數

管理祕密最簡單的解決方案就是使用環境變數。 環境變數有數個優點:

  • 它們很容易使用
  • 它們適用於所有系統(即使在內部部署系統中)
  • 每個人都知道他們,並了解他們的運作方式

不過,它們不夠安全:系統上的所有進程都可以讀取它們,而且很容易在 Java 系統上使用 Java 管理延伸模組 (JMX) 公開它們。

因此,環境變數通常被視為零信任的第一個步驟:比直接將祕密儲存在原始程式碼中更安全,但環境變數缺乏管理功能,而且容易為攻擊者存取。

使用 Kubernetes 祕密

Kubernetes 具有 secrets 的概念,這是另一個良好的解決方案。 這些祕密可以載入為應用程式檔案系統中的檔案:JAVA 程式可在啟動階段讀取該檔案,以存取這些祕密。 Spring Framework 等工具甚至為此機制提供標準支援,允許其以簡單且有效率的方式使用這些祕密。

此機制比環境變數更安全,因為這些檔案只能由需要它們的程式讀取。 其同時也受益於豐富的 Kubernetes 生態系統,可由各種管理工具管理,包括雲端提供者提供的工具。

雖然 Kubernetes 祕密是良好的 Kubernetes 解決方案,但也僅限於 Kubernetes,而且缺少進階管理功能,隨管理 Kubernetes 基礎結構所用的工具而異。

使用祕密存放區

像是 Hashicorp Vault 或 Azure 金鑰保存庫 的秘密存放區是用於管理秘密的特殊軟體。 其提供豐富的管理系統以授權使用者、輪替安全性金鑰,以及驗證哪些應用程式可以存取哪些祕密。

其也提供外部 API,以便在任何系統上使用。 例如,您可以在所有 Azure 服務上使用 Azure Key Vault,包括虛擬機器、Azure 應用程式服務、Azure Kubernetes Services 或 Azure Spring 應用程式。

秘密存放區是管理秘密的最安全解決方案,但它們需要使用專用工具。