我正在使用 Amazon SES 接收电子邮件,然后通过规则集将其存储在 Amazon S3 中。这些消息然后由我用 Java 编写的程序检索。
整个过程目前正在像魅力一样工作。当我尝试加密电子邮件时,麻烦就来了……
以下是我的流程步骤:
- SES 接收电子邮件
- SES 使用 KMS 密钥加密电子邮件(感谢 SES 规则集)。
- SES 将电子邮件存储在 Amazon S3 上
- 我的 Java 应用程序从 S3 检索邮件。
但是,当我在 S3 上调用以检索电子邮件时,出现以下错误:
com.amazonaws.services.kms.model.AWSKMSException: The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access. (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: 8de11099-1706-11e8-a931-c7b8c61f94bc)
如此错误中所述,我认为我用来检索 S3 对象的用户无权访问用于加密消息的密钥。但据我了解亚马逊的政策如何运作,我相信一切都是正确的(显然不是)。
有人知道我做错了什么或者我可以尝试做些什么吗?
下面是有关当前配置的信息,例如我的用户和 KMS 密钥的策略,以及我正在使用的 Java 代码。
地区
The S3 bucket is in EU_WEST_1 (Ireland)
The key has been created in the EU_WEST_1 (Ireland) region
用户政策(详见附图)
这里使用的用户名是delivery
AmazonS3FullAccess
AWSKeyManagementServicePowerUser
关键政策
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111222333444:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": [
"AIDAIEIV9CCM6CQJBN7HA",
"arn:aws:iam::111222333444:user/delivery"
]
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"AIDAIEIV9CCM6CQJBN7HA",
"arn:aws:iam::111222333444:user/delivery"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": [
"AIDAIEIV9CCM6CQJBN7HA",
"arn:aws:iam::111222333444:user/delivery"
]
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
},
{
"Sid": "AllowSESToEncryptMessagesBelongingToThisAccount",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:GenerateDataKey*"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:EncryptionContext:aws:ses:source-account": "111222333444"
},
"Null": {
"kms:EncryptionContext:aws:ses:rule-name": "false",
"kms:EncryptionContext:aws:ses:message-id": "false"
}
}
}
]
}
S3 存储桶策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSESPuts-111222333444",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::received-emails.my-company-name/*",
"Condition": {
"StringEquals": {
"aws:Referer": "111222333444"
}
}
}
]
}
Java 代码
private static void getS3Object() {
// Use credentials to login.
BasicAWSCredentials awsCred = new BasicAWSCredentials("user access key", "user secret");
AWSCredentialsProvider credentialProvider = new AWSStaticCredentialsProvider(awsCred);
KMSEncryptionMaterialsProvider materialsProvider = new KMSEncryptionMaterialsProvider("id of the key");
AmazonS3Encryption s3Client = AmazonS3EncryptionClientBuilder
.standard()
.withCryptoConfiguration(new CryptoConfiguration(CryptoMode.EncryptionOnly))
.withEncryptionMaterials(materialsProvider)
.withCredentials(credentialProvider)
.withRegion(Regions.EU_WEST_1).build();
// Get the object from S3
GetObjectRequest request = new GetObjectRequest(new S3ObjectId("Bucket name", "Object key"));
S3Object object = s3Client.getObject(request);
}
在此先感谢您的帮助!