AWS TransferManager теряет метаданные, связанные с шифрованием, при записи с помощью AmazonS3Encryption
Нам нужно передать некоторые большие файлы на S3 и зашифровать их во время передачи. Я хочу использовать AWSTransferManager
чтобы воспользоваться преимуществами многокомпонентной загрузки и других функций.
В AmazonS3Encryption
клиент напишет два поля метаданных x-amz-iv
(вектор инициализации) и x-amz-key
(ключ содержимого) в расположение S3, и эти два поля необходимы для расшифровки файла.
Тем не менее TransferManager
теряет эти значения метаданных и не записывает их в расположение. Я пытаюсь увидеть, есть ли способ добраться до них и либо заставить их записать, либо добавить их в местоположение после завершения передачи.
Я обнаружил эту старую проблему, которая, похоже, очень тесно связана, она довольно старая, и я думаю, что с тех пор API изменились, и предлагаемые обходные пути не работают для меня, потому что я не могу найти способ получить поля метаданных из клиент s3.
https://github.com/aws/aws-sdk-java/issues/367
Насколько я понимаю, ключ содержимого зашифрован для каждого клиента s3, а IV предоставляется для каждого файла, поэтому мне нужно будет обращаться к клиенту сразу после того, как он записал каждый файл.
В соответствии с документами AWS я создаю AmazonS3Encryption
как это:
AmazonS3Encryption s3Encryption = AmazonS3EncryptionClientBuilder
.standard()
.withRegion(Regions.US_WEST_2)
.withCryptoConfiguration(new CryptoConfiguration(CryptoMode.EncryptionOnly))
.withEncryptionMaterials(new StaticEncryptionMaterialsProvider(new EncryptionMaterials(secretKey)))
.build();
А затем построение TransferManager
как это:
TransferManager transferManager =
TransferManagerBuilder.standard().withS3Client(s3Encryption).build();
я пытался transferManager.upload()
а также варианты, такие как uploadFileList()
что позволяет мне предоставлять ObjectMetadataProvider
но я не могу найти способ записать метаданные.
Я нашел то, что считаю дымящимся пистолетом, UploadCallable
класс в AWS:
private UploadResult uploadInOneChunk() {
PutObjectResult putObjectResult = s3.putObject(origReq);
UploadResult uploadResult = new UploadResult();
uploadResult.setBucketName(origReq.getBucketName());
uploadResult.setKey(origReq.getKey());
uploadResult.setETag(putObjectResult.getETag());
uploadResult.setVersionId(putObjectResult.getVersionId());
return uploadResult;
}
В PutObjectResult
вернулся из s3
содержит нужные мне метаданные, но, к сожалению, они просто игнорируются и возвращается другой результат.
Я копался в коде, пытаясь найти ловушку, чтобы сделать это, не прибегая к ужасным хитростям Java Reflection. Пока я пробовал:
- Подклассы
AmazonS3EncryptionClient
, что невозможно, потому что его класс построителяpublic final
- Предоставление альтернативного
UploadCallable
кTransferManager
, не могу найти для этого крючка - Как добраться до
AmazonS3EncryptionClient
внутренние криптоклассы экземпляра, которые содержат нужные мне значения, но все они частные и скрыты на нескольких уровнях
и т. д. На данный момент я думаю, что мой единственный вариант - либо TransferManager
или просто жить с прямым клиентом s3, но это кажется довольно значительным недостатком в клиенте AWS, поэтому мне интересно, не упускаю ли я чего-то. Спасибо за любую помощь.