Amazon S3 v2 Has Behavioural Difference When Use KMS Encryption
abilhanli opened this issue · 1 comments
Upcoming End-of-Support
- 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)
Hi @abilhanli
There's a little confusion when it comes to the v1 encryption client: we indeed have a AmazonS3EncryptionClientV2, but in this case both v1 and v2 Encryption Clients are in the com.amazonaws
groupId, so it means both are in the end-of-support path.
The equivalent of the Encryption Client in Java SDK v2 is the standalone Amazon S3 Encryption Client 3.x:
<groupId>software.amazon.encryption.s3</groupId>
<artifactId>amazon-s3-encryption-client-java</artifactId>
<version>3.x</version>
The S3 Encryption Client 3.x is maintained by the Encryption Tools team, and the project has its own Github repo: https://github.com/aws/amazon-s3-encryption-client-java. There's some Migration to 3.x tips in the Developer Guide here. I suggest you try the 3.x encryption client and see if the issue still persists, and if it does please open an issue in the new repo.
For more info on Java SDK v1 to v2 migration, check the Migrate to version 2 section of the AWS SDK for Java Dev Guide.