Amazon SCS-C02: 加密、KMS 與機密管理 — 學習指南
屬於 AWS Security Specialty SCS-C02 — 學習指南. 使用經過驗證的解答練習: Amazon 考試中心, 或參加限時模擬考試: ExamRoll.io.
AWS KMS 金鑰類型、政策與存取控制
AWS KMS 支援三大類金鑰,選擇正確的類型決定了誰能控制金鑰材料、它儲存在哪裡,以及如何輪換。AWS 擁有的金鑰對您來說是不可見的、不需費用,並在您啟用 SSE-S3 時由 S3 等服務使用。AWS 管理的金鑰 (別名為 aws/<service>) 讓服務可以代表您進行加密,但您無法修改其金鑰政策,這就是為什麼它們不適用於跨帳戶存取或精細的治理。客戶管理的金鑰 (CMK) 是主力:您可以控制金鑰政策、輪換 (每年自動或隨需)、授權 (grant)、別名和刪除等待期。
有兩種特殊的變體值得注意。當法規或 BYOK (自備金鑰) 要求您必須在 AWS 外部產生金鑰材料並將其匯入 KMS 金鑰時,就會使用匯入的金鑰材料。匯入的材料是設定金鑰材料明確到期日的唯一方法——由 AWS 產生的 CMK 永不過期。您無法對匯入的金鑰啟用 AWS 的年度自動輪換;您必須自己重新匯入材料。多區域金鑰透過複本金鑰在不同區域間共享相同的金鑰 ID 和材料,因此在 us-east-1 產生的密文可以在 us-west-1 解密,無需重新加密。每個複本都有其獨立的金鑰政策和別名,但加密材料是同步的。
最常被誤解的控制項是 KMS 金鑰政策。與大多數 AWS 資源僅靠 IAM 政策就能授予存取權不同,KMS 金鑰使用其金鑰政策作為最根本的授權來源。一個授予金鑰 kms:Decrypt 權限的 IAM 政策是無效的,除非金鑰政策也將存取權委派給 IAM (透過將帳戶根使用者設為 Principal 並加上適當的陳述式,或直接指定 principal)。這就是為什麼即使是擁有 AdministratorAccess 的工程師,在對一個其政策不信任該帳戶的 CMK 呼叫 Decrypt 時,仍然會收到 AccessDenied。標準的委派陳述式如下所示:
{
"Sid": "EnableIAMPermissions",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:root" },
"Action": "kms:*",
"Resource": "*"
}
授權 (Grant) 和 ViaService 條件增加了分層的限制——例如,透過 kms:ViaService: s3.us-east-1.amazonaws.com 強制金鑰只能在特定區域透過 S3 使用。
伺服器端與用戶端加密
對於 S3,兩種常見的伺服器端選項主要在控制權和可稽核性方面有所不同:
- SSE-S3 (AES-256): S3 完全管理金鑰;沒有客戶可見的金鑰政策,沒有針對每個金鑰的 CloudTrail 解密事件,也無法進行跨帳戶治理。對於基本的靜態加密來說已經足夠,但當合規性要求需要證明誰解密了資料時,這就不足了。
- SSE-KMS: 使用您控制的 CMK;每次解密呼叫都會被記錄,金鑰政策會強制執行存取控制,並且您可以透過加密內容 (encryption context) 進行限制。它的每次請求成本較高,且會消耗 KMS 的 TPS 配額,因此應啟用儲存貯體金鑰 (
BucketKeyEnabled: true) 來大幅減少對 KMS 的呼叫。
當資料必須在離開應用程式前加密,或儲存服務絕不能看到明文時,使用 AWS Encryption SDK 進行用戶端加密是合適的。高吞吐量的工作負載應使用快取加密材料管理器 (CachingCryptoMaterialsManager) 來包裝 SDK,它會在可設定的位元組、訊息和 TTL 限制內,跨多個訊息重複使用資料金鑰。若沒有快取,每次 encrypt 呼叫都會觸發一次 GenerateDataKey 請求,這會迅速耗盡 KMS 請求配額並增加成本。
from aws_encryption_sdk import CachingCryptoMaterialsManager, LocalCryptoMaterialsCache
cache = LocalCryptoMaterialsCache(capacity=100)
ccmm = CachingCryptoMaterialsManager(
master_key_provider=mkp, cache=cache,
max_age=600.0, max_messages_encrypted=10000)
Secrets Manager 與 Parameter Store
Secrets Manager 使用 KMS CMK 加密儲存憑證,並透過 Lambda 函數支援自動輪換——AWS 為 RDS、Redshift 和 DocumentDB 提供了範本,而自訂的 Lambda 則可處理其他任何情況。輪換會執行一個四步驟的狀態機 (createSecret, setSecret, testSecret, finishSecret),在將新憑證提升為 AWSCURRENT 之前,會先將其暫存在 AWSPENDING 標籤下。應用程式應捕捉驗證失敗、刷新秘密並重試——這種模式可以消除停機時間,因為先前的憑證會透過 AWSPREVIOUS 短暫地保持有效。
當輪換用的 Lambda 在 VPC 內執行時 (通常是為了存取私有的 RDS 執行個體),它需要對外的網路存取權限以連線到 Secrets Manager 服務端點。在沒有 NAT 的私有 VPC 中,您必須部署一個介面 VPC 端點 (com.amazonaws.<region>.secretsmanager),並允許該 Lambda 的安全群組在 443 連接埠上存取該端點。忘記這一點是個典型的失敗情境:輪換看起來設定好了,但每次調用都逾時。
為了實現跨區域彈性,請使用多區域 KMS 金鑰和 Secrets Manager 的複本秘密功能。在 us-east-1 的主要秘密是使用主要 CMK 加密的;在 us-west-1 的複本則是使用複本 CMK 來解密。像 alias/prod-db 這樣的別名可以隨需指向新的金鑰 ID,以實現快速的金鑰輪換,而無需更改應用程式碼。
當您不需要輪換功能時,Parameter Store 的 SecureString 類型是一個輕量級的替代方案。這兩種服務都在 CloudFormation 中提供動態參考 ({{resolve:secretsmanager:MySecret:SecretString:password}}),這樣堆疊範本就永遠不會嵌入明文。
EBS、RDS、Aurora 與快照加密
靜態加密是在建立磁碟區或執行個體時啟用,且無法原地切換。對於不合規的未加密資源,其修復模式是進行帶有加密的快照複本:
aws ec2 copy-snapshot --source-snapshot-id snap-abc \
--source-region us-east-1 --encrypted \
--kms-key-id alias/prod-ebs
aws ec2 create-volume --snapshot-id snap-newEncrypted ...
對於 RDS 和 Aurora,將加密的快照還原到一個新的執行個體,然後進行切換。跨帳戶復原需要共享快照,並且透過金鑰政策授予目標帳戶對 CMK 的 kms:CreateGrant 和 kms:Decrypt 權限——僅共享快照會失敗,因為目標帳戶無法解密資料金鑰。應啟用帳戶層級的 EBS 預設加密,這樣無論呼叫者的行為如何,新建立的磁碟區都會被加密。
TLS:ACM 與 ALB 政策
當綁定到整合式服務(ALB、CloudFront、API Gateway)時,ACM 會免費核發並自動續簽公開憑證。憑證無法匯出,所以若要在 EC2 上終止 TLS,需要使用 ACM Private CA(用於可匯出的私有憑證)或匯入的憑證。一個務實的模式是:在 ALB 上使用 ACM 憑證來終止公開的 TLS,如果需要端對端加密,則在 ALB 到 EC2 這一段使用自簽或私有 CA 的憑證。使用像是 ELBSecurityPolicy-TLS13-1-2-2021-06 這樣的安全政策,強制用戶端使用現代的加密套件,這個政策會停用 TLS 1.0/1.1 和較弱的套件。
常見陷阱
沒有金鑰政策的 IAM。 在 IAM 政策中授予 kms:Decrypt 權限,但 CMK 的金鑰政策卻省略了帳戶主體,會導致 AccessDenied。KMS 將金鑰政策視為權威來源;IAM 權限只能在金鑰政策允許的範圍內進一步限制。
沒有 VPC 端點的輪換 Lambda。 如果 Lambda 在私有子網路中執行,而 VPC 沒有 NAT 且沒有 secretsmanager 介面端點,那麼對 secretsmanager.<region>.amazonaws.com 的輪換呼叫將無法解析或連線。端點上的安全群組也必須允許來自 Lambda 安全群組的 443 連接埠流量。
將 SSE-S3 等同於 SSE-KMS。 SSE-S3 使用 AWS 擁有的金鑰,沒有客戶可編輯的政策,CloudTrail 中也沒有每個物件的解密日誌,且不支援跨帳戶金鑰共享。它滿足了「靜態加密」的勾選項目,但無法強制規定哪些主體可以解密特定物件——只有使用 CMK 的 SSE-KMS 才能提供這種治理能力。
實務問題:使用案例情境
情境: Meridian Financial 營運一個多帳戶的 AWS Organization,其中包含一個安全帳戶、獨立的生產/非生產帳戶、在 ECS/EKS 中由 ALB 支援的微服務、RDS/Aurora 叢集、由 EBS 支援的 EC2 執行個體,以及 S3 資料湖。開發人員和自動化流程目前混合使用 AWS 管理的金鑰、純文字的 SSM 參數,以及偶爾在帳戶之間手動共享快照。
挑戰: 一名工程師意外地將一個未加密的 RDS 快照共享給第三方帳戶,並且發現數個 API 憑證以純文字的 SecureString 參數形式儲存,這造成了資料外洩和未經授權的還原存取風險。
建議方法:
- 在安全帳戶中建立一個組織範圍、客戶管理的 AWS KMS 對稱式 CMK,其金鑰政策透過
aws:PrincipalOrgID授予成員帳戶使用權限,並啟用自動輪換;對於短期的跨帳戶操作,則使用授權 (grants)。 - 透過複製未加密的 RDS 快照和任何 EBS 快照來修復現有的產物,同時選擇新的 CMK 以產生加密副本,然後刪除原始的未加密快照;設定帳戶預設值,讓新的 RDS 和 EBS 預設建立加密資源。
- 將機密遷移到以 CMK 加密的 AWS Secrets Manager(或 SSM Parameter Store SecureString)中,透過 Lambda 為資料庫憑證啟用 Secrets Manager 自動輪換,並使用基於資源的政策和最小權限的 IAM 角色來限制存取。
- 透過佈建 ACM 管理的 TLS 憑證並將其附加到具有現代 TLS 政策(TLS 1.2/1.3)的 ALB 上,來強制執行傳輸中加密,並設定資料庫和用戶端要求 TLS 連線。
- 透過護欄 (guardrails) 防止再次發生:應用服務控制政策 (Service Control Policies) 來拒絕建立/共享未加密的快照和未加密的 S3 上傳,啟用 AWS Config 規則以檢查資源是否加密,並透過 CloudTrail 和 CloudWatch Alarms 監控 KMS 和 Secrets Manager 的使用情況。
基本原理: 具有組織層級政策的中央 CMK、自動化重新加密、用於機密生命週期管理的 Secrets Manager、TLS 強制執行以及預防性護欄,這些都遵循 AWS 的最小權限和深度防禦最佳實踐,以消除純文字機密和未經授權的快照存取。
客戶管理的 CMK:多區域、匯入材料與金鑰政策
客戶管理的 CMK (Customer Managed CMK) 是您在 AWS 中擁有的資料進行每一項密碼學操作的控制平面。最常決定一個設計是成功還是導致服務中斷的三個屬性是:金鑰的區域拓撲、其金鑰材料的來源,以及附加於其上的政策。
多區域金鑰是一組位於不同 AWS 區域的 KMS 金鑰,它們共享相同的金鑰 ID,且最關鍵的是,共享相同的底層金鑰材料。它們不會像 DynamoDB 全域資料表那樣自動複寫——您需要使用 ReplicateKey 從一個主金鑰明確地建立複本。由於所有複本的金鑰材料都相同,因此在 us-east-1 產生的密文可以在 us-west-1 解密,而無需進行跨區域的 KMS 呼叫。這正是在跨區域複寫 Secrets Manager 秘密時所需要的特性:位於容錯移轉區域的複本秘密必須能夠在本地解密,這樣既能消除每次 GetSecretValue 的跨區域延遲,又能在主區域發生服務中斷時存活。單一區域的 CMK 無法支援位於另一個區域的 Secrets Manager 複本,因此正確的模式是:使用多區域 CMK 加密主秘密,將該金鑰複寫到目標區域,然後在複寫秘密時指向該複本 CMK。
aws kms create-key --multi-region --region us-east-1
aws kms replicate-key --key-id mrk-abc123 \
--replica-region us-west-1
aws secretsmanager replicate-secret-to-regions \
--secret-id prod/db \
--add-replica-regions Region=us-west-1,KmsKeyId=mrk-abc123
匯入的金鑰材料(外部來源,Origin=EXTERNAL)指的是您在 AWS 外部產生原始的 AES-256 材料,然後將其匯入一個 KMS 金鑰殼層中。AWS 永遠不會在 HSM 的受保護記憶體之外擁有該材料的副本,也沒有任何備份。如果您刪除了匯入的材料——無論是透過 DeleteImportedKeyMaterial 還是因為其到期日已過——該金鑰的狀態會變成 PendingImport,且所有用該金鑰產生的密文都將無法復原,除非您重新匯入完全相同的位元組。這是在某些情況下的復原路徑,例如,當一個 EBS 磁碟區因為其加密的資料金鑰無法解密而掛載失敗時:從您的離線託管重新匯入相同的金鑰材料,該磁碟區就能再次使用。AWS 端沒有還原選項,沒有輪換技巧,也沒有任何支援工單可以復原已刪除的匯入材料。請將離線副本視為第零層(tier-zero)的基礎設施。
金鑰政策是每個 KMS 金鑰的信任根。與單獨使用 IAM 不同,KMS 要求在金鑰政策本身中明確允許;一個授予 kms:Decrypt 的 IAM 政策是無效的,除非金鑰政策將權限委派給 IAM(即 "Principal": {"AWS": "arn:aws:iam::111122223333:root"} 結合條件陳述式)。對於跨帳戶使用,金鑰的政策必須明確指定外部帳戶或主體,然後外部帳戶必須透過 IAM 授予其自己的使用者權限。忘記設定金鑰政策這端,是跨帳戶 Secrets Manager 失敗最常見的原因——Secrets Manager 的資源政策允許外部主體呼叫 GetSecretValue,但底層的 Decrypt 操作卻因為 CMK 仍然拒絕該呼叫者而失敗。
Secrets Manager 與 Parameter Store SecureString 的使用模式
Secrets Manager 和 SSM Parameter Store SecureStrings 都將加密工作委派給 KMS,但它們在成本、輪換語意和跨區域行為上有所不同。Secrets Manager 支援原生的多區域複寫、帶有預備標籤(AWSCURRENT、AWSPENDING)的版本控制,以及由 Lambda 支援的輪換。Parameter Store SecureString 則較為便宜,能與階層式路徑整合,並且適用於不常輪換的設定檔形式的秘密。
對於跨帳戶存取,您必須更新秘密上的資源政策(或是在 Parameter Store 消費者帳戶中的 IAM 政策)以及加密 CMK 上的 KMS 金鑰政策,兩者缺一不可。認為僅有 Secrets Manager 權限就足夠是錯誤的,因為擷取工作流程總是會對 CMK 執行一個隱含的 kms:Decrypt 操作;如果金鑰政策沒有允許外部帳戶,即使秘密本身的政策已滿足,呼叫者在 Decrypt 步驟仍會收到 AccessDeniedException。
| 服務 | 特性 |
|---|---|
| Secrets Manager | 受管輪換、JSON 結構、約 $0.40/每個秘密/每月、內建多區域複寫 |
| Parameter Store SecureString (Advanced) | 存放多個值時較便宜、每個參數 8 KB、無內建跨區域複寫 |
| Parameter Store SecureString (Standard) | KMS 加密參數的免費方案,最高 4 KB、無輪換框架 |
信封加密、儲存貯體金鑰與授權權杖
信封加密 (Envelope encryption) 意指 KMS 絕不會接觸到您的大量資料。您呼叫 GenerateDataKey,此 API 會回傳一個明文資料金鑰 (在本地端用來以 AES-GCM 加密您的資料) 以及該資料金鑰的一份加密副本 (與密文儲存在一起)。若要解密,您需對被包裝的資料金鑰呼叫 Decrypt,並在本地端重新推導出明文金鑰。這個模式至關重要,因為 KMS 有請求配額 (依區域、依金鑰計算) 且每次 API 呼叫都會計價。如果您對每筆 4 KB 的記錄都直接呼叫 Encrypt,您將會遇到節流和成本遽增的問題;但如果您為每一批次或每個檔案產生一個資料金鑰,吞吐量就能與您本地端的加密函式庫成線性擴展。
S3 儲存貯體金鑰 (Bucket Keys) 在 S3 內部為 SSE-KMS 套用了相同的原則。若沒有儲存貯體金鑰,每次對 SSE-KMS 物件的 PUT 和 GET 操作都會產生一次 GenerateDataKey 或 Decrypt 呼叫。對於一個每秒接收數千個物件的儲存貯體來說,這會導致 KMS 節流和意料之外的 KMS 帳單。啟用儲存貯體金鑰會讓 S3 在儲存貯體層級產生一個短期的金鑰,並為多個物件重複使用它,從而將 KMS 的請求量減少數個數量級:
aws s3api put-bucket-encryption --bucket app-data \
--server-side-encryption-configuration '{
"Rules":[{
"ApplyServerSideEncryptionByDefault":{
"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/app"},
"BucketKeyEnabled":true}]}'
授權 (Grants) 是金鑰政策之外,另一種用於臨時性、細緻化權限委派的方法。它們在操作上很重要,因為有最終一致性的問題:在 CreateGrant 回傳後,該授權並不會立即對區域中的每個 KMS 端點可見。如果一個用戶端在幾毫秒後嘗試進行 Encrypt,它可能會收到 AccessDeniedException。CreateGrant 的回應主體中包含一個 GrantToken 字串,當後續的 KMS 呼叫透過 --grant-tokens 參數傳遞此權杖時,KMS 會被強制立即承認該授權,無論其傳播狀態如何。
TOKEN=$(aws kms create-grant --key-id $KEY \
--grantee-principal arn:aws:iam::111122223333:role/worker \
--operations Encrypt Decrypt --query GrantToken --output text)
aws kms encrypt --key-id $KEY --plaintext fileb://payload \
--grant-tokens "$TOKEN"
依賴帶有退避機制的重試而非使用授權權杖,是一種可行但較差的緩解措施——它會浪費延遲時間,且在高負載下仍可能失敗。標準的最佳解法永遠是:由建立授權的服務回傳授權權杖,並要求呼叫者在其第一個操作中出示它。
實務問題:使用案例情境
情境: Meridian Financial 公司在一個多帳戶的 AWS 環境中營運,其 S3 中存有客戶的 PII (個人可識別資訊),RDS 中有交易型資料庫,並透過 Lambda 進行無伺服器處理。他們使用客戶自管的 CMK 搭配匯入的金鑰材料,以符合區域性的金鑰保管規定,並將金鑰複寫到第二個區域以進行災難復原。
挑戰: 最近一次稽核發現一個設定錯誤的 KMS 金鑰政策,允許了跨帳戶解密;此外,一位外部稽核員需要臨時存取權限來解密一部分 S3 物件。Meridian 公司還需要安全的秘密輪換機制,以及對大型物件的高效率加密方式,以控制 KMS 的請求成本。
建議方法:
- 將 AWS KMS 中設定錯誤的 CMK 政策輪換為一個最低權限原則的政策,明確地僅授予必要的 IAM principal 和角色,並使用 KMS 多區域金鑰為 DR 建立一個多區域複本 CMK。
- 根據合規時間範圍,重新匯入或排程匯入金鑰材料的生命週期管理,並使用 AWS Config 和 EventBridge 啟用金鑰材料自動過期/輪換的通知。
- 對於稽核員,建立一個具有短暫 TTL 的 KMS 授權 (grant),並在稽核員的 assume-role 工作階段中立即使用授權權杖 (grant token),以允許臨時的解密操作,而無需更改金鑰政策。
- 將長期有效的憑證移至 AWS Secrets Manager,並將其輪換機制與底層服務 (RDS 或 API 金鑰) 透過 Lambda 綁定;將基礎設施參數作為 Systems Manager Parameter Store 的 SecureString 儲存非輪換項目,並強制使用 CMK 和嚴格的基於資源的政策進行加密。
- 在應用程式碼中或透過 AWS SDK 呼叫 KMS 的 GenerateDataKey (Encrypt/Decrypt),為大型 S3 物件實作信封加密,並啟用 S3 儲存貯體金鑰以減少大型物件伺服器端加密的 KMS 請求量和成本。
- 啟用 CloudTrail 記錄和 KMS 金鑰使用記錄,並建立 CloudWatch Alarms/GuardDuty 規則,以便在發生非預期的解密操作或授權建立時發出警報。
理由: 此方法強制執行金鑰的最低權限存取,維持匯入材料的合規性與多區域的業務連續性,使用臨時授權來提供安全的第三方存取,透過輪換機制集中管理秘密,並根據 AWS 最佳實踐優化 KMS 的使用和成本。
← 日誌、稽核與鑑識 · 所有領域 · 資料保護與 S3 →
練習這些題目 → · 在 ExamRoll.io 上限時練習 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通過考試 →