aws / aws-encryption-sdk-java

AWS Encryption SDK
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html
Apache License 2.0
224 stars 123 forks source link

[Question] What is the appropriate dependency to import to upgrade from 2.4.1 to 3.0.0? #2044

Closed dbwiddis closed 2 months ago

dbwiddis commented 2 months ago

Problem:

I am trying to upgrade from 2.4.1 to 3.0.1. The Release Notes for 3.0.0 (un)helpfully state:

⚠ BREAKING CHANGES

  • This feature update includes a breaking change that requires AWS SDK v2 Java as a hard dependency.

OK, great. So I went to these docs and added these lines to my build.gradle:

-    implementation 'com.amazonaws:aws-encryption-sdk-java:2.4.1'
+    implementation 'com.amazonaws:aws-encryption-sdk-java:3.0.1'
+    implementation(platform("software.amazon.awssdk:bom:2.27.19"))
+    implementation 'software.amazon.awssdk:sdk-core:2.27.19'

That still doesn't resolve it.

Here's the method that no longer compiles in v3:

    String encrypt(final String credential) {
        final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt).build();
        byte[] bytes = Base64.getDecoder().decode(masterKey);
        JceMasterKey jceMasterKey = JceMasterKey.getInstance(new SecretKeySpec(bytes, ALGORITHM), PROVIDER, "", WRAPPING_ALGORITHM);
        // This line no longer compiles
        final CryptoResult<byte[], JceMasterKey> encryptResult = crypto.encryptData(
            jceMasterKey,
            credential.getBytes(StandardCharsets.UTF_8)
        );
        return Base64.getEncoder().encodeToString(encryptResult.getResult());
    }

The error message is:

error: cannot access ICryptographicMaterialsManager
> Task :compileJava
        final CryptoResult<byte[], JceMasterKey> encryptResult = crypto.encryptData(
                                                                       ^
  class file for software.amazon.cryptography.materialproviders.ICryptographicMaterialsManager not found

A web search for ICryptographicMaterialsManager shows the Encryption SDK as the only result.

Looking at the pom.xml for this project, I tried

    implementation 'software.amazon.cryptography:aws-cryptographic-material-providers:1.0.2'

This compiles, but fails with

        java.lang.ExceptionInInitializerError: Exception java.lang.NoClassDefFoundError: dafny/TypeDescriptor$Initializer [in thread "TEST-EncryptorUtilsTests.testEncryptDecryptTemplateCredential-seed#[D0A96CF60B545007]"]
            at software.amazon.cryptography.materialproviders.internaldafny.types.MaterialProvidersConfig.<clinit>(MaterialProvidersConfig.java:38)
            at software.amazon.cryptography.materialproviders.ToDafny.MaterialProvidersConfig(ToDafny.java:715)
            at software.amazon.cryptography.materialproviders.MaterialProviders.<init>(MaterialProviders.java:50)
            at software.amazon.cryptography.materialproviders.MaterialProviders$BuilderImpl.build(MaterialProviders.java:429)
            at com.amazonaws.encryptionsdk.AwsCrypto$Builder.build(AwsCrypto.java:214)

Solution:

Please give more clear details in either the release notes, or an "Upgrading" doc, or point me to anywhere this is clearly documented how to upgrade. The reference to "AWS SDK v2 Java" is not useful in actually determining the appropriate dependency.

dbwiddis commented 2 months ago

Updating to note that I have resolved this.

It's not the breaking change that was the issue; my build.gradle was not resolving transitive dependencies for some reason unknown to me (but probably associated with a gradle plugin that tries to avoid jar hell). The following worked for me

    implementation "com.amazonaws:aws-encryption-sdk-java:3.0.1"
    implementation "software.amazon.cryptography:aws-cryptographic-material-providers:1.0.2"
    implementation "org.dafny:DafnyRuntime:4.2.0"
    implementation "software.amazon.smithy.dafny:conversion:0.1"

On the way, when I thought it was the problem, I also struggled with getting the bom imported per the README here. Figured out that the Spring Dependency Management Plugin works great for importing Maven-based bom definitions into Gradle. Ended up not needing the BOM but it's useful for the future.

Closing this issue as it's resolved.