介绍
私有导出文件需要在存储之前加密。你将加密一个小型合成文件,让一个读取者恢复原始字节,诊断解密失败,并安排密钥清理。
请先完成 在 LabEx 上开始学习 AWS、为报告读取者授予最小权限 和 通过 IAM 角色使用临时凭证。这个全新 VM 提供独立的文件、读取角色会话和参考密钥。
加密私有导出文件
本步骤中,你将创建 AWS Key Management Service(KMS)密钥,并将提供的导出文件转换为密文。使用提供的合成 private-export.json,不要使用个人数据。export-reader 配置档使用准备好的读取角色临时会话,最初没有 KMS 权限。保留 alias/labex-sec01-reference。
打开 Terminal 旁的 AWS View,比较密钥状态、读取者授权和加密请求结果。其中的字节哈希可以让你比较结果,而不显示私有数据。
对称密钥使用相同的受保护密钥材料进行加密和解密;KMS 将这些材料保存在服务内部。别名为密钥提供可读名称,不会替代其唯一的密钥 ARN。
从提供的项目目录开始。cd 更改当前目录;调用者查询确认准备好的操作者身份,不打印凭证。
cd /home/labex/project
aws sts get-caller-identity --query Arn --output text
预期看到 labex-sec01-operator 用户 ARN。创建自己的密钥。--query 从响应中选择一个字段,--output text 去除 JSON 引号,$(...) 将结果存储到 shell 变量,供后续命令使用。
KEY_ARN=$(aws kms create-key --description labex-sec01-owned-export --query KeyMetadata.Arn --output text)
aws kms create-alias --alias-name alias/labex-sec01-private-export --target-key-id "$KEY_ARN"
aws kms describe-key --key-id "$KEY_ARN" --query 'KeyMetadata.[KeyState,KeySpec]' --output text
预期看到 Enabled 和 SYMMETRIC_DEFAULT。不要使用或修改参考密钥。

官方 Console 对照:别名、Enabled 状态和 ARN 对应刚查询的密钥身份与状态。这些是 AWS 示例值;继续在 Terminal 中使用自己的 KEY_ARN。
来源:AWS KMS。
加密上下文是绑定到密文的一组非秘密标签。解密时必须提供相同标签。这里的 Purpose=private-export 标识这个导出文件的预期用途。上下文值不应用于存放密码或个人数据。
KMS Encrypt 处理小型明文;准备好的导出文件远低于 4 KiB 限制。fileb:// 按二进制字节读取输入。CLI 将返回的密文表示为 base64;base64 --decode 将其转回二进制文件。管道将输出传给下一条命令,> 将结果写入指定文件。
aws kms encrypt --key-id "$KEY_ARN" --plaintext fileb://private-export.json --encryption-context Purpose=private-export --query CiphertextBlob --output text | base64 --decode > private-export.kms
使用 sha256sum 比较字节哈希。不同的哈希表明密文与原始数据不同;仅凭这一点不能证明权限。
sha256sum private-export.json private-export.kms
打开 AWS View。Customer key inventory 应显示已启用的密钥,Cryptographic requests 应显示允许的操作者 Encrypt 请求,其输入与导出文件匹配。
授予一个读取角色访问权限
本步骤中,你将让应用读取者仅使用导出密钥解密。IAM 角色权限同时指定动作及其适用资源。kms:Decrypt 允许恢复字节,不会授予加密或密钥管理权限。

读取者需要正确的上下文、Decrypt 授权和已启用的密钥,才能恢复导出文件。
添加授权之前,先尝试读取者配置档。--profile export-reader 选择准备好的临时角色会话,而不是操作者。命令必须以访问拒绝响应失败,且不能返回明文。
aws kms decrypt --profile export-reader --key-id "$KEY_ARN" --ciphertext-blob fileb://private-export.kms --encryption-context Purpose=private-export --query KeyId --output text
创建策略文档。here-document 将 <<EOF 和 EOF 之间的行写入 read-export.json;shell 将 $KEY_ARN 展开为准确的密钥 ARN。这个授权既不使用通配符动作,也不使用通配符资源。
cat > read-export.json <<EOF
{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow", "Action": "kms:Decrypt", "Resource": "$KEY_ARN"}]
}
EOF
将这个内联策略附加到读取角色。内联策略属于该角色,可以在清理时独立移除。提供的密钥使用标准的同账户密钥策略,允许 IAM 权限授权这个角色。
aws iam put-role-policy --role-name labex-sec01-export-reader --policy-name ReadPrivateExport --policy-document file://read-export.json
现在使用读取者会话恢复加密字节。命令选择 base64 明文字段,解码,并写入恢复的导出文件,不显示内容。
aws kms decrypt --profile export-reader --key-id "$KEY_ARN" --ciphertext-blob fileb://private-export.kms --encryption-context Purpose=private-export --query Plaintext --output text | base64 --decode > restored-export.json
cmp 比较实际文件字节。使用 && 后,只有比较成功才会打印消息。
cmp private-export.json restored-export.json && echo "Original export bytes recovered"
预期看到 Original export bytes recovered。AWS View 应显示限定到准确密钥的读取者策略,以及允许的读取角色 Decrypt,其恢复字节与导出文件匹配。将这个角色保持为仅能对你的密钥执行 Decrypt。

诊断三种解密失败
本步骤中,你将区分上下文、权限和密钥状态失败。始终使用相同密文,让每个结果的原因清晰。下方失败命令有意只选择密钥标识符,从不选择明文。
先只更改上下文值。即使读取者已获授权,也不能使用错误上下文解密密文。
aws kms decrypt --profile export-reader --key-id "$KEY_ARN" --ciphertext-blob fileb://private-export.kms --encryption-context Purpose=wrong-context --query KeyId --output text
预期看到 InvalidCiphertextException。密钥和角色授权仍然存在,但上下文与 Encrypt 使用的上下文不匹配。
接着移除角色授权,再重复正确上下文的请求。移除内联策略会改变授权,不会修改密钥或密文。
aws iam delete-role-policy --role-name labex-sec01-export-reader --policy-name ReadPrivateExport
aws kms decrypt --profile export-reader --key-id "$KEY_ARN" --ciphertext-blob fileb://private-export.kms --encryption-context Purpose=private-export --query KeyId --output text
预期得到访问拒绝响应。下一次测试之前,先恢复限定范围的授权。
aws iam put-role-policy --role-name labex-sec01-export-reader --policy-name ReadPrivateExport --policy-document file://read-export.json
最后禁用密钥。禁用的密钥仍在清单中,但不能执行加密操作。使用具有权限的操作者配置档,以单独观察密钥状态失败。
aws kms disable-key --key-id "$KEY_ARN"
aws kms decrypt --key-id "$KEY_ARN" --ciphertext-blob fileb://private-export.kms --encryption-context Purpose=private-export --query KeyId --output text
预期看到 DisabledException。启用密钥,再重复成功的读取者恢复操作,确认正常行为已恢复。
aws kms enable-key --key-id "$KEY_ARN"
aws kms decrypt --profile export-reader --key-id "$KEY_ARN" --ciphertext-blob fileb://private-export.kms --encryption-context Purpose=private-export --query Plaintext --output text | base64 --decode > restored-export.json
cmp private-export.json restored-export.json && echo "Reader access restored"
检查 AWS View 的 Cryptographic requests 表。比较被拒绝请求的调用者、上下文和结果。角色授权无法修复上下文不匹配或密钥禁用。

安全停用本实验密钥
本步骤中,你将移除读取者授权和别名,再仅为自己的导出密钥安排删除。KMS 密钥删除有等待期:PendingDeletion 是预期的即时状态,不代表密钥已经消失。这个期间,密钥不能解密。
安排删除之前,确认 ARN 仍属于本实验的导出密钥。
aws kms describe-key --key-id "$KEY_ARN" --query 'KeyMetadata.[Description,KeyState]' --output text
预期看到 labex-sec01-owned-export 和 Enabled。仅移除你添加的角色授权和创建的别名。
aws iam delete-role-policy --role-name labex-sec01-export-reader --policy-name ReadPrivateExport
aws kms delete-alias --alias-name alias/labex-sec01-private-export
使用最短的七天等待期安排密钥删除。
aws kms schedule-key-deletion --key-id "$KEY_ARN" --pending-window-in-days 7 --query DeletionDate --output text
命令返回计划删除日期。通过独立读取确认实际密钥状态,并保留无关的参考密钥。
aws kms describe-key --key-id "$KEY_ARN" --query KeyMetadata.KeyState --output text
aws kms describe-key --key-id alias/labex-sec01-reference --query KeyMetadata.KeyState --output text
预期自己的密钥为 PendingDeletion,参考密钥为 Enabled。AWS View 应显示没有读取者授权,并显示 Reference preserved。使用 rm -f 仅移除指定的本地导出文件;文件不存在时也不会报错,不会删除其他项目文件。
rm -f private-export.json private-export.kms restored-export.json read-export.json
在操作者配置档仍可用时,运行本步骤的验证。通过后,移除这个 VM 的临时 CLI 配置档,并取消密钥变量。这会移除本地会话凭证,不会取消计划中的云密钥删除。
rm -f /home/labex/.aws/credentials /home/labex/.aws/config
unset KEY_ARN
总结
你使用客户 KMS 密钥和非秘密上下文加密了实际导出字节,授予一个读取角色对准确密钥执行 Decrypt 的权限,并恢复了原始字节。错误上下文、移除授权和禁用密钥分别产生不同失败。随后,你通过删除等待期停用本实验密钥,同时保留无关的参考密钥。



