如何与加密的SQS队列进行交互? KMS密钥访问不起作用

时间:2019-04-08 16:07:42

标签: java amazon-web-services amazon-cloudformation

我正在尝试通过Java SDK与加密的SQS队列进行交互。

应用程序正在发送响应:

AmazonSQSException: 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.

但是,我看到该密钥确实存在,并且正在尝试给予适当的访问权限。

我认为执行此操作时会出现一些错误。请看下面-

SDK互动

意图:从一个队列读取并写入另一个队列。尝试接收消息时,在第4行之后失败。

public void replayQueue(QueuePair queuePair) {
    ReceiveMessageRequest messageRequest = new ReceiveMessageRequest()
            .withQueueUrl(queuePair.getDlq());
    log.info("Constructed receive request: " + messageRequest.toString());
    sqs.receiveMessage(messageRequest).getMessages().stream()
            .forEach(message -> {
                log.info("Inside stream. Message: " + message.toString());
                SendMessageRequest request = new SendMessageRequest()
                        .withQueueUrl(queuePair.getSource())
                        .withMessageBody(message.getBody());
                log.info("Send request: " + request);
                SendMessageResult result = sqs.sendMessage(request);
                log.info("Sent messages to " + queuePair.getSource() + " with result of: " + result.toString());
                    }
            );
}

密钥创建

密钥是在另一个微服务的模板中创建的,并且对于该服务正常工作。

ApplicationKmsKeyForSqs:
Type: AWS::KMS::Key
Properties:
  Description: Encrypts messages published to SQS from SNS
  KeyPolicy:
    Version: 2012-10-17
    Id: !Sub ${DNSEndPoint}-application-${Environment}-sqs-kms-key
    Statement:
    - Sid: Enable IAM User Permission
      Effect: Allow
      Principal:
        AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
      Action:
      - kms:*
      Resource: '*'
    - Sid: Allow SQS to use the key
      Effect: Allow
      Principal:
        Service: sqs.amazonaws.com
      Action:
      - kms:GenerateDataKey*
      - kms:Decrypt
      Resource: '*'

ApplicationKMSKeyAlias:
Type: AWS::KMS::Alias
Properties:
  AliasName: !Sub 'alias/application-${Environment}-sqs-kms-key'
  TargetKeyId: !Ref ApplicationKmsKeyForSqs

我可以看到该密钥存在于AWS控制台中并且具有正确的别名。

向应用程序授予权限

此策略应授予我的应用程序使用其他微服务中创建的密钥的权限。

ApplicationPolicy:
Type: AWS::IAM::Policy
Properties:
  PolicyName: app-policy
  PolicyDocument:
    Version: 2012-10-17
    Statement:
      - Effect: Allow
        Action:
          - sqs:*
        Resource: !Sub arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:*${Environment}*
      - Effect: Allow
        Action:
          - kms:Encrypt
          - kms:Decrypt
          - kms:GenerateDataKey*
          - kms:*
        Resource: !Sub arn:aws:kms:us-east-1:${AWS::AccountId}:alias/application-${Environment}-sqs-kms-key

有鉴于此,我认为:

  1. 钥匙显然存在
  2. 它在正确的区域
  3. 我正在授予它访问权限(或尝试访问)

所以我想知道是否还有其他我想念的东西。密钥是否应该作为请求的一部分发送?我为它授予访问权限的方式有问题吗?

任何提示将不胜感激。

1 个答案:

答案 0 :(得分:0)

在您实施 KMS 密钥时,您仅提供对 SQS 的访问权限以使用 KMS 密钥进行解密。由于 SQS 使用服务器端加密进行加密,因此需要对其进行扩展,以便 sqs 也可以加密。

- Sid: Allow SQS to use the key
  Effect: Allow
  Principal:
    Service: sqs.amazonaws.com
  Action:
  - kms:GenerateDataKey*
  - kms:Decrypt
  - kms:Encrypt
  Resource: '*'

然后,lambda 函数需要对 kms:Decrypt 和 kms:GenerateDataKey 的 KMS 密钥的许可。

亚马逊文档: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html#send-to-encrypted-queue