Я наследую кодовую базу, которая использует Java AWS SDK для генерации предопределенных URL-адресов S3 для объектов Puting и Getting. Код выглядит примерно так:
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, filename);
request.setMethod(HttpMethod.PUT);
request.setExpiration(new DateTime().plusMinutes(30).toDate());
request.setContentType("image/jpeg");
String url = awss3.generatePresignedUrl(request);
И эта существующая кодовая база всегда работала и очень близка к работе. Однако одно бизнес-требование, которое изменилось, заключается в том, что нам необходимо зашифровать содержимое корзины S3. Поэтому, естественно, я установил шифрование по умолчанию в корзине на AWS-KMS (так как оно казалось самым современным) и выбрал ключ по умолчанию «aws / s3», который был создан для моей учетной записи.
Однако теперь, когда конечный пользователь пытается фактически использовать URL-адреса, которые я генерирую в их браузере, появляется следующее сообщение об ошибке:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<code>InvalidArgument</code>
<Message>Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>null</ArgumentValue>
<RequestId>...</RequestId>
<HostId>...</HostId>
</Error>
Мой вопрос совершенно неясен: как мне снова заставить это работать? На мой взгляд, есть два разных пути, по которым я мог бы пойти. Либо: 1) я мог бы понизить кодирование с AWS-KMS до AES-256 и надеяться, что все это работает, или 2) я могу внести некоторые изменения в свой клиентский код для поддержки KMS, что, вероятно, потребует загрузки ключ KMS через AWS SDK и использование его для подписи запросов, а также, возможно, добавление авторизации и других заголовков.
Вариант 1 выглядит менее трудоемким, но также менее идеальным, потому что кто знает, всегда ли будет поддерживаться менее безопасная форма шифрования. Вариант 2 кажется более концептуально лучшим выбором, но он также вызывает некоторые опасения, потому что он кажется намного более трудоемким, и я беспокоюсь о необходимости включать дополнительные заголовки. Код, который я показал выше, отражает эквивалент запроса PutObject (прокси через сгенерированный URL), но есть также эквиваленты запросов GetObject для загрузки изображений, которые, возможно, отображаются непосредственно в браузере. Было бы намного сложнее написать там код внешнего интерфейса, чтобы использовать разные заголовки только для визуализации изображения. (Интересно, могут ли параметры запроса заменять заголовки?)
В любом случае, что мне нужно изменить в Java, чтобы это работало с AWS KMS? Нужно ли использовать AWS SDK для «загрузки» ключа KMS, как я и подозревал? И должен ли я пойти по этому пути, или AES-256 действительно будет лучшим вариантом?