aws-sdk-java icon indicating copy to clipboard operation
aws-sdk-java copied to clipboard

Amazon S3 v2 Has Behavioural Difference When Use KMS Encryption

Open abilhanli opened this issue 1 year ago • 0 comments

Upcoming End-of-Support

  • [X] I acknowledge the upcoming end-of-support for AWS SDK for Java v1 was announced, and migration to AWS SDK for Java v2 is recommended.

Describe the bug

Essentially, we are going to move to AWS JAVA SDK Version 2 from V1, due to end of support. Based on migration guide https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/s3-encryption-migration.html It is suggested to do followings:

1. Update existing clients to read new formats. Update your application to use version 1.11.837 or later of the AWS SDK for Java and redeploy the application. This enables the Amazon S3 client-side encryption service clients in your application to decrypt objects created by V2 service clients. If your application uses multiple AWS SDKs, you must update each SDK separately.
2. Migrate encryption and decryption clients to V2. Once all of your V1 encryption clients can read V2 encryption formats, update the Amazon S3 client-side encryption and decryption clients in your application code to use their V2 equivalents.

We upgraded our dependencies to latest 1.+.

    api 'com.amazonaws:aws-java-sdk-s3:1.12.747'
    api 'com.amazonaws:aws-java-sdk-core:1.12.747'
    api 'com.amazonaws:aws-java-sdk-kms:1.12.747'

After we use V2 objects from V1 jar, we noticed that an extra validation introduced in V2 which is to validate KMS materials. Because of the validation an checked exception thrown with a message like Provided encryption materials do not match information retrieved from the encrypted object by AWS API which we can not handle in our service, taking consideration the client builder obj is used and all those validations are hidden in the API.

As a result, our integration test is failing. If we simply fix our integration tests and ignore it, we might end up a customer impact.

We kindly ask make this new validation optional.

Expected Behavior

We do not have the Exception explained in the bug, when using V1 objects. This suggests that V2 is not backward compatible due to the additional validation for encryption materials.

We expect that V1 behaviour is kept in V2.

Could you please make this validation optional to make it backward compatible?

Current Behavior

After using the version 2 objects, we had following exception

Caused by: java.lang.IllegalStateException: Provided encryption materials do not match information retrieved from the encrypted object
    at com.amazonaws.services.s3.internal.crypto.v2.ContentCryptoMaterial.validateMaterialsForDecrypt(ContentCryptoMaterial.java:857)
    at com.amazonaws.services.s3.internal.crypto.v2.ContentCryptoMaterial.fromObjectMetadata0(ContentCryptoMaterial.java:390)
    at com.amazonaws.services.s3.internal.crypto.v2.ContentCryptoMaterial.fromObjectMetadata(ContentCryptoMaterial.java:342)
    at com.amazonaws.services.s3.internal.crypto.v2.S3CryptoModuleAE.decipherWithMetadata(S3CryptoModuleAE.java:263)
    at com.amazonaws.services.s3.internal.crypto.v2.S3CryptoModuleAE.decipher(S3CryptoModuleAE.java:158)
    at com.amazonaws.services.s3.internal.crypto.v2.S3CryptoModuleAE.getObjectSecurely(S3CryptoModuleAE.java:136)
    at com.amazonaws.services.s3.AmazonS3EncryptionClientV2.getObject(AmazonS3EncryptionClientV2.java:241)
    at 

Reproduction Steps

In order to reproduce to same exception, you can simply provide a kms id which is different than what is used in encrypted obj and then call getObject method on the client.

The code block to create an encrypted client object using V2 could be like

    protected AWSKMS getAWSKMS(AWSCredentials awsCredentials, String KMSRegion) {
        return AWSKMSClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withRegion(KMSRegion) //String value
                .build();
    }

protected AmazonS3EncryptionClientV2Builder getAmazonS3EncryptionClientBuilderV2(AWSCredentials awsCredentials, String KMSRegion, String kmsKeyId) {
        AWSKMS kmsClient = getAWSKMS(awsCredentials, KMSRegion);

        return AmazonS3EncryptionClientV2Builder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withKmsClient(kmsClient)
                .withCryptoConfiguration(
                        new CryptoConfigurationV2().withCryptoMode(CryptoMode.AuthenticatedEncryption).withRangeGetMode(CryptoRangeGetMode.ALL))
                .withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(kmsKeyId));
    }

and then call the client like

s3Client.getObject(new GetObjectRequest(bucket, objectName));

Possible Solution

Make it optional to be backward compatible.

Additional Information/Context

No response

AWS Java SDK version used

1.12.747(Version 2 objects based on migration guide)

JDK version used

11

Operating System and version

Mac Osx 14.5 (23F79)

abilhanli avatar Jun 24 '24 23:06 abilhanli