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:

https://github.com/aws/aws-sdk-java/blob/ccfd63c097874e3a1e9ffda7bf171769b6bd3b21/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/transfer/internal/UploadCallable.java

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, поэтому мне интересно, не упускаю ли я чего-то. Спасибо за любую помощь.

0 ответов

Другие вопросы по тегам