GithubHelp home page GithubHelp logo

aws / aws-encryption-sdk-java Goto Github PK

View Code? Open in Web Editor NEW
216.0 35.0 121.0 38.54 MB

AWS Encryption SDK

Home Page: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html

License: Apache License 2.0

Java 99.93% Shell 0.07%

aws-encryption-sdk-java's Introduction

AWS Encryption SDK for Java

The AWS Encryption SDK enables secure client-side encryption. It uses cryptography best practices to protect your data and protect the encryption keys that protect your data. Each data object is protected with a unique data encryption key, and the data encryption key is protected with a key encryption key called a wrapping key or master key. The encryption method returns a single, portable encrypted message that contains the encrypted data and the encrypted data key, so you don't need to keep track of the data encryption keys for your data. You can use KMS keys in AWS Key Management Service (AWS KMS) as wrapping keys. The AWS Encryption SDK also provides APIs to define and use encryption keys from other key providers.

The AWS Encryption SDK for Java provides methods for encrypting and decrypting strings, byte arrays, and byte streams. For details, see the example code and the Javadoc.

For more details about the design and architecture of the AWS Encryption SDK, see the AWS Encryption SDK Developer Guide.

Security issue notifications

See Support Policy for details on the current support status of all major versions of this library.

Getting Started

Required Prerequisites

To use the AWS Encryption SDK for Java you must have:

  • A Java 8 or newer development environment

    If you do not have one, we recommend Amazon Corretto.

    Note: If you use the Oracle JDK, you must also download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.

  • Declare a Dependency on the AWS Encryption SDK in Java and its dependencies

    This library requires the AWS Cryptographic Material Providers Library in Java, and the KMS and DynamoDB clients from the AWS Java SDK V2.

    The KMS client from the AWS SDK for Java V1 is an optional dependency.

    Note: The AWS Cryptographic Material Providers Library in Java only supports the AWS SDK for Java V2 and requires a HARD dependency on the AWS SDK for Java V2's KMS and DynamoDB clients, regardless of whether a KMS Keyring or Hierarchical Keyring is used.

    • Via Apache Maven
      Add the following to your project's pom.xml.

      <project>
      ...
      <dependencyManagement>
       <dependencies>
          <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.20.91</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
       </dependencies>
      </dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-encryption-sdk-java</artifactId>
          <version>3.0.0</version>
        </dependency>
        <dependency>
          <groupId>software.amazon.cryptography</groupId>
          <artifactId>aws-cryptographic-material-providers</artifactId>
          <version>1.0.2</version>
        </dependency>
        <dependency>
          <groupId>software.amazon.awssdk</groupId>
          <artifactId>dynamodb</artifactId>
        </dependency>
        <dependency>
          <groupId>software.amazon.awssdk</groupId>
          <artifactId>kms</artifactId>
        </dependency>
        <!-- The following are optional -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
            <version>1.12.394</version>
            <optional>true</optional>
        </dependency>
      </dependencies>
      ...
      </project>
    • Via Gradle Kotlin
      In a Gradle Java Project, add the following to the dependencies section:

      implementation("com.amazonaws:aws-encryption-sdk-java:3.0.0")
      implementation("software.amazon.cryptography:aws-cryptographic-material-providers:1.0.2")
      implementation(platform("software.amazon.awssdk:bom:2.20.91"))
      implementation("software.amazon.awssdk:kms")
      implementation("software.amazon.awssdk:dynamodb")
      // The following are optional:
      implementation("com.amazonaws:aws-java-sdk:1.12.394")
  • Bouncy Castle or Bouncy Castle FIPS

    The AWS Encryption SDK for Java uses Bouncy Castle to serialize and deserialize cryptographic objects. It does not explicitly use Bouncy Castle (or any other JCA Provider) for the underlying cryptography. Instead, it uses the platform default, which you can configure or override as documented in the Java Cryptography Architecture (JCA) Reference Guide.

    If you do not have Bouncy Castle, go to https://bouncycastle.org/latest_releases.html, then download the provider file that corresponds to your JDK. Or, you can pick it up from Maven (groupId: org.bouncycastle, artifactId: bcprov-jdk18on).

    Beginning in version 1.6.1, the AWS Encryption SDK for Java also works with Bouncy Castle FIPS (groupId: org.bouncycastle, artifactId: bc-fips) as an alternative to non-FIPS Bouncy Castle. For help installing and configuring Bouncy Castle FIPS, see BC FIPS documentation, in particular, User Guides and Security Policy.

Optional Prerequisites

AWS Integration

You don't need an Amazon Web Services (AWS) account to use the AWS Encryption SDK, but some example code require an AWS account, an AWS KMS key, and the AWS SDK for Java (either 1.x or 2.x). Note that the KmsAsyncClient is not supported, only the synchronous client.

Amazon Corretto Crypto Provider

Many users find that the Amazon Corretto Crypto Provider (ACCP) significantly improves the performance of the AWS Encryption SDK. For help installing and using ACCP, see the amazon-corretto-crypto-provider repository.

Get Started

To get started with the AWS Encryption SDK for Java

  1. Instantiate the AWS Encryption SDK.
  2. Create a Keyring from the AWS Cryptographic Material Providers Library.
  3. Encrypt and decrypt data.
// This sample code encrypts and then decrypts a string using an AWS KMS key.
// You provide the KMS key ARN and plaintext string as arguments.
package com.amazonaws.crypto.examples;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoResult;
import software.amazon.cryptography.materialproviders.IKeyring;
import software.amazon.cryptography.materialproviders.MaterialProviders;
import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput;
import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

public class StringExample {
    private static String keyArn;
    private static String plaintext;

    public static void main(final String[] args) {
        keyArn = args[0];
        plaintext = args[1];

        // Instantiate the SDK
        final AwsCrypto crypto = AwsCrypto.standard();
        
        // Create the AWS KMS keyring.
        // We create a multi keyring, as this interface creates the KMS client for us automatically.
        final MaterialProviders materialProviders = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMultiKeyringInput keyringInput = 
                CreateAwsKmsMultiKeyringInput.builder().generator(keyArn).build();
        final IKeyring kmsKeyring = materialProviders.CreateAwsKmsMultiKeyring(keyringInput);
        
        // Set up the encryption context
        // NOTE: Encrypted data should have associated encryption context
        // to protect its integrity. This example uses placeholder values.
        // For more information about the encryption context, see
        // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
        final Map<String, String> encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue");

        // Encrypt the data
        final CryptoResult<byte[], ?> encryptResult = crypto.encryptData(kmsKeyring, plaintext.getBytes(StandardCharsets.UTF_8), encryptionContext);
        final byte[] ciphertext = encryptResult.getResult();
        System.out.println("Ciphertext: " + Arrays.toString(ciphertext));

        // Decrypt the data
        final CryptoResult<byte[], ?> decryptResult = 
                crypto.decryptData(
                        kmsKeyring, 
                        ciphertext,
                        // Verify that the encryption context in the result contains the
                        // encryption context supplied to the encryptData method
                        encryptionContext);

        assert Arrays.equals(decryptResult.getResult(), plaintext.getBytes(StandardCharsets.UTF_8));

        // The data is correct, so return it. 
        System.out.println("Decrypted: " + new String(decryptResult.getResult(), StandardCharsets.UTF_8));
    }
}

You can find more examples in the example directory.

Public API

Our versioning policy applies to all public and protected classes/methods/fields in the com.amazonaws.encryptionsdk package unless otherwise documented.

The com.amazonaws.encryptionsdk.internal package is not included in this public API.

FAQ

See the Frequently Asked Questions page in the official documentation.

aws-encryption-sdk-java's People

Contributors

acioc avatar ajewellamz avatar alex-chew avatar dbwiddis avatar dependabot[bot] avatar farleyb-amazon avatar hyandell avatar imabhichow avatar johnwalker avatar josecorella avatar joshbean avatar juneb avatar lavaleri avatar lizroth avatar lucasmcdonald3 avatar mattsb42-aws avatar praus avatar robin-aws avatar rustanleino avatar salusasecondus avatar scottarc avatar seebees avatar semantic-release-bot avatar shayvana avatar slyubomirsky avatar smswz avatar sparecycles avatar sullis avatar texastony avatar wesleyrosenblum avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-encryption-sdk-java's Issues

Support Re-Key Operation in AwsCrypto

For scenarios like key-rotation, I think it would be very useful to support a re-keying operation, where we decrypt the data key using one master key, and then re-encrypt with another master key. This also leverages the convenient envelope structure of the encrypted payload. I've noticed this is supported using the KMS Client (re-keying happens on the server side in that case), but feels like it should also exist in the SDK as well!

Thoughts?

Nick

CC: @Walliee

Performance hit after using AWS Encryption SDK vs Bouncy Castle SDK

Hi,

Can I use AWS Encryption SDK to encrypt/decrypt a plaintext data of 32 char without using KMS service?

I would like to provide my own SECRET KEY to encrypt/decrypt data. I have used bouncy castle SDK to do that but it takes 40 seconds to process 1 million encrypt/decrypt. Can AWS Encryption SDK help to improve performance of 1 million encrypt/decrypt to 20 seconds?

Thanks,
Bipin

Remove hard cryptographic dependency on BouncyCastle

Right now this code depends on BouncyCastle for several cases:

  • EC Key generation (to support next point)
  • EC Key (de)serialization with point-compression
  • RSA encryption/decryption (due to default java JCE problems with OAEP not using SHA-1)
  • ECDSA signatures
  • HMAC-based Extract-and-Expand Key Derivation Function

To make this library more portable, we should remove all of these hard dependencies. This will require:

  • Implementing point (de)compression
  • Properly using AlgorithmParameterSpec to configure the JCE provider to do the right OAEP padding
  • Replace HKDFBytesGenerator with Hkdf.java from aws-dynamodb-encryption-java
  • Remove all other references to BouncyCastle.

Optimizing Decryption: using MultipleProviderFactory.buildMultiProvider

Currently MultipleProviderFactory.buildMultiProvider accepts the ordered list of CMK keys.
The first CMK becomes default to generate DataKey by hitting KMS.
At the time of decryption, the same CMK is used to decrypt the encrypted DataKey.

Assuming that first CMK (passed in MultipleProviderFactory.buildMultiProvider) is always the application server's default or closest KMS region is not always true. Programmer/DevOps team can configure the CMKs in out of order. Due to this, the farthest KMS server will always get the hit even though its not in the same region as of the application server. This could lead to increase of latency.

We could optimize the list by reshuffling the CMKs list by putting the one as first element which is in the same region as of application server.

Any thoughts?

Parallel encryption across multiple regions

When multiple encryption providers are defined, can the DefaultCryptoMaterialsManager encrypt the additional providers in parallel rather than serially? Biggest use case for this would be having KMS providers defined in multiple disparate regions (Asia/Europe/US) and reducing the time waiting for each to contact them.

Thanks!

Encryption SDK throws AwsCryptoException

I am trying to integrate Encryption SDK with Apache NiFi.
NiFi already includes following versions of bouncy castle dependencies:-

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpg-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-ext-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>

But it throws below exception:-

2018-08-20 15:07:59,192 WARN [Timer-Driven Process Thread-5] o.a.n.controller.tasks.ConnectableTask Administratively Yielding AWSEncryptionProcessor[id=56b1bbfc-0165-1000-d94c-c242aa619d1b] due to uncaught Exception: com.amazonaws.encryptionsdk.exception.AwsCryptoException: java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
com.amazonaws.encryptionsdk.exception.AwsCryptoException: java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
	at com.amazonaws.encryptionsdk.DefaultCryptoMaterialsManager.getMaterialsForEncrypt(DefaultCryptoMaterialsManager.java:63)
	at com.amazonaws.encryptionsdk.AwsCrypto.encryptData(AwsCrypto.java:248)
	at com.amazonaws.encryptionsdk.AwsCrypto.encryptData(AwsCrypto.java:228)
	at org.apache.nifi.processors.aws.encryption.AWSEncryptionProcessor.onTrigger(AWSEncryptionProcessor.java:146)
	at org.apache.nifi.processor.AbstractProcessor.onTrigger(AbstractProcessor.java:27)
	at org.apache.nifi.controller.StandardProcessorNode.onTrigger(StandardProcessorNode.java:1165)
	at org.apache.nifi.controller.tasks.ConnectableTask.invoke(ConnectableTask.java:203)
	at org.apache.nifi.controller.scheduling.TimerDrivenSchedulingAgent$1.run(TimerDrivenSchedulingAgent.java:117)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.InvalidAlgorithmParameterException: parameter object not a ECParameterSpec
	at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$EC.initialize(Unknown Source)
	at com.amazonaws.encryptionsdk.internal.TrailingSignatureAlgorithm$ECDSASignatureAlgorithm.generateKey(TrailingSignatureAlgorithm.java:88)
	at com.amazonaws.encryptionsdk.DefaultCryptoMaterialsManager.generateTrailingSigKeyPair(DefaultCryptoMaterialsManager.java:151)
	at com.amazonaws.encryptionsdk.DefaultCryptoMaterialsManager.getMaterialsForEncrypt(DefaultCryptoMaterialsManager.java:54)
	... 14 common frames omitted


Any leads where things could be wrong?

encryptionsdk.exception.BadCiphertextException: Invalid ciphertext type.

Hi Guys,
I am using aws encryption sdk to encrypt and decrypt files. I am getting "encryptionsdk.exception.BadCiphertextException: Invalid ciphertext type" in the following scenario.

I am encrypting my file using command:
aws kms encrypt --key-id keyId --region us-east-1 --plaintext file://text.txt --query CipherTextBlob --output text | base64 --decode >file.dat.encrypted.

I my code I have:
AwsCrypto awsCrypto = new AwsCrypto();
InputStream inputStream = new FileInputStream("inputfile");
final CryptoInputStream decryptingStream = awsCrypto.createDecryptingStream(provider,inputStream);
OutputStream outputStream = new FileOutputStream("outputFile");
IOUtils.copy(decryptingStream,outputStream)

Could anyone please point out what I am missing in this. I am trying to figure out the problem but I am not able to. Would appreciate any help regarding this.

Thanks.

Backwards compatibility issue with alias/name and getMasterkey

In 1.3.1 I could get a MasterKeyProvider using aliases and regions. In the code below I have a list of regions (this.regions) where the alias (this.keyId) has been created in each. I create the KmsMasterKeyProvider for each region and return a MultiProvider.

    private MasterKeyProvider<?> masterKeyProvider() {

        AWSCredentialsProvider credentials
                = new DefaultAWSCredentialsProviderChain();

        List<KmsMasterKey> masterKeys
                = new LinkedList<>();

        for (String region : this.regions) {

            KmsMasterKeyProvider provider
                    = new KmsMasterKeyProvider(
                            credentials,
                            Region.getRegion(
                                    Regions.fromName(
                                            region)),
                            new ClientConfiguration(),
                            this.keyId);

            masterKeys.add(
                    provider.getMasterKey(
                            this.keyId));
        }

        return MultipleProviderFactory
                .buildMultiProvider(
                        masterKeys);
    }

I can then use the MultiProvider with AwsCrypto like so...

                CryptoOutputStream<?> encryptingStream
                        = awsCrypto
                                .createEncryptingStream(
                                        masterKeyProvider(),
                                        fileOutputStram))

This no longer works. The getMasteKeyMethod at line 452 of the KmsMasterKeyProvider.java now requires an ARN for the keyId.

String regionName = parseRegionfromKeyArn(keyId);

The result is that regionName is null.

Is there another way to do what I'm trying to do? Thanks.

M

Issue with getting Region when federated

Wondering if there is an issue with getting the region when the profile is federated. I am in a federated account using a role that has kms:*, and I get this when decrypting:

com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys

This is not an issue with using aliases. This works perfect in another account where I am not federated, using an IAM User with full admin permissions. Is there something else needed here?

    @Override
    public void decryptFile(
            final String encryptedFilename, 
            final String decryptedFilename) {

        final KmsMasterKeyProvider provider
                = new KmsMasterKeyProvider(
                        new DefaultAWSCredentialsProviderChain());

        final AwsCrypto awsCrypto
                = new AwsCrypto();

        try (final FileInputStream fileInputStream
                = new FileInputStream(
                        encryptedFilename);

                final FileOutputStream fileOutputStream
                        = new FileOutputStream(
                                decryptedFilename);

                final CryptoInputStream<?> decryptingStream
                        = awsCrypto
                                .createDecryptingStream(
                                        provider, 
                                        fileInputStream)) {

            IOUtils.copy(
                    decryptingStream,
                    fileOutputStream);

        } catch (IOException exception) {
            throw new DecryptionException(exception);
        }
    }

decryptData parses headers twice

When using AwsCrypto.decryptData(), the headers are parsed in the DecryptionHandler() constructor as well as in the processBytes() call for the DecryptHandler. This is less than an ideal because each time the headers are parsed the data keys are decrypted. For AWS KMS keys, this means two api calls to decrypt the same data key for each call to decryptData.

Encryption uses "key/" ARN and not the "alias/" ARN

This is problematic when trying to provide a PolicyDocument to an instance profile. I need to allow decrypt privileges the key/* ARNs instead of the alias/* ARNs. Impossible to programmatically do that. Would be much better if I could allows decrypt privileges to the alias/* ARNs as I can easily construct those.

MasterKeyProvider.decryptDataKey(...) is called twice

In AwsCrypto. decryptData(...), the call to decryptDataKey is called twice.
1> at https://github.com/awslabs/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java#L242
where DecryptHandler is trying to read header and decrypts the data key.

2> at https://github.com/awslabs/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java#L248
the read header method is again called and hence trying to decrypt the same data key.

Library performance

How much of a performance impact is there (if any at all) to doing AES-GCM encryption with generating a new data key for each encryption operation VS other modes of encryption where we wouldn't generate a new data key for each encryption operation? Have any benchmarks of this library vs other libraries been published?

MultiProvider doesn't fallback with KMS if access denied or wrong credentials provided

MultiProvider with KMS doesn't fallback to another key in the following scenarios:

  1. Key exists but no permissions to access it. Exception:

User: XXX is not authorized to perform: kms:GenerateDataKey on resource:XXX (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: XXX)
com.amazonaws.AmazonServiceException: User: XXX is not authorized to perform: kms:GenerateDataKey on resource: XXX (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: XXX)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1383)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:902)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:607)
at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:376)
at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:338)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:287)
at com.amazonaws.services.kms.AWSKMSClient.invoke(AWSKMSClient.java:2497)
at com.amazonaws.services.kms.AWSKMSClient.generateDataKey(AWSKMSClient.java:1347)
at com.amazonaws.encryptionsdk.kms.KmsMasterKey.generateDataKey(KmsMasterKey.java:95)
at com.amazonaws.encryptionsdk.internal.EncryptionHandler.(EncryptionHandler.java:130)
at com.amazonaws.encryptionsdk.AwsCrypto.encryptData(AwsCrypto.java:185)
at com.amazonaws.encryptionsdk.AwsCrypto.encryptData(AwsCrypto.java:201)
at AWSKeyEncryptionService.doEncrypt(EncryptionService.scala:64)
at EncryptionServiceLoggingSupport$class.encrypt(EncryptionService.scala:78)
at AWSKeyEncryptionService.encrypt(EncryptionService.scala:43)
at AWSKeyEncryptionServiceIT$$anonfun$1.apply$mcV$sp(AWSKeyEncryptionServiceIT.scala:17)
at AWSKeyEncryptionServiceIT$$anonfun$1.apply(AWSKeyEncryptionServiceIT.scala:14)
at AWSKeyEncryptionServiceIT$$anonfun$1.apply(AWSKeyEncryptionServiceIT.scala:14)

  1. Wrong secret key provided. Exception:

...
com.amazonaws.AmazonServiceException: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
...
at com.amazonaws.encryptionsdk.kms.KmsMasterKey.encryptDataKey(KmsMasterKey.java:149)

AbortedException when decrypting dataKey

Hi, i'm working on a Java 8 application hosted on Amazon and sometimes (not all the times) i'm getting the following exception when decrypting a secret:

com.amazonaws.AbortedException: 
	at com.amazonaws.internal.SdkFilterInputStream.abortIfNeeded(SdkFilterInputStream.java:53)
	at com.amazonaws.internal.SdkFilterInputStream.markSupported(SdkFilterInputStream.java:117)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1012)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
	at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
	at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
	at com.amazonaws.services.kms.AWSKMSClient.doInvoke(AWSKMSClient.java:3202)
	at com.amazonaws.services.kms.AWSKMSClient.invoke(AWSKMSClient.java:3178)
	at com.amazonaws.services.kms.AWSKMSClient.executeDecrypt(AWSKMSClient.java:835)
	at com.amazonaws.services.kms.AWSKMSClient.decrypt(AWSKMSClient.java:810)
	at com.amazonaws.encryptionsdk.kms.KmsMasterKey.decryptDataKey(KmsMasterKey.java:171)
	at com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider.decryptDataKey(KmsMasterKeyProvider.java:561)
	... 22 common frames omitted
Wrapped by: com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys
	at com.amazonaws.encryptionsdk.MasterKeyProvider.buildCannotDecryptDksException(MasterKeyProvider.java:106)
	at com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider.decryptDataKey(KmsMasterKeyProvider.java:567)
	at com.amazonaws.encryptionsdk.multi.MultipleProviderFactory$MultiProvider.decryptDataKey(MultipleProviderFactory.java:150)
	... 21 common frames omitted
	Suppressed: com.amazonaws.AbortedException: 
		at com.amazonaws.internal.SdkFilterInputStream.abortIfNeeded(SdkFilterInputStream.java:53)
		at com.amazonaws.internal.SdkFilterInputStream.markSupported(SdkFilterInputStream.java:117)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1012)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
		at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
		at com.amazonaws.services.kms.AWSKMSClient.doInvoke(AWSKMSClient.java:3202)
		at com.amazonaws.services.kms.AWSKMSClient.invoke(AWSKMSClient.java:3178)
		at com.amazonaws.services.kms.AWSKMSClient.executeDecrypt(AWSKMSClient.java:835)
		at com.amazonaws.services.kms.AWSKMSClient.decrypt(AWSKMSClient.java:810)
		at com.amazonaws.encryptionsdk.kms.KmsMasterKey.decryptDataKey(KmsMasterKey.java:171)
		at com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider.decryptDataKey(KmsMasterKeyProvider.java:561)
		... 22 common frames omitted
	Suppressed: com.amazonaws.AbortedException: 
		at com.amazonaws.internal.SdkFilterInputStream.abortIfNeeded(SdkFilterInputStream.java:53)
		at com.amazonaws.internal.SdkFilterInputStream.markSupported(SdkFilterInputStream.java:117)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1012)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
		at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
		at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
		at com.amazonaws.services.kms.AWSKMSClient.doInvoke(AWSKMSClient.java:3202)
		at com.amazonaws.services.kms.AWSKMSClient.invoke(AWSKMSClient.java:3178)
		at com.amazonaws.services.kms.AWSKMSClient.executeDecrypt(AWSKMSClient.java:835)
		at com.amazonaws.services.kms.AWSKMSClient.decrypt(AWSKMSClient.java:810)
		at com.amazonaws.encryptionsdk.kms.KmsMasterKey.decryptDataKey(KmsMasterKey.java:171)
		at com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider.decryptDataKey(KmsMasterKeyProvider.java:561)
		... 22 common frames omitted
Wrapped by: com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys
	at com.amazonaws.encryptionsdk.MasterKeyProvider.buildCannotDecryptDksException(MasterKeyProvider.java:106)
	at com.amazonaws.encryptionsdk.multi.MultipleProviderFactory$MultiProvider.decryptDataKey(MultipleProviderFactory.java:158)
	at com.amazonaws.encryptionsdk.DefaultCryptoMaterialsManager.decryptMaterials(DefaultCryptoMaterialsManager.java:108)
	at com.amazonaws.encryptionsdk.internal.DecryptionHandler.readHeaderFields(DecryptionHandler.java:455)
	at com.amazonaws.encryptionsdk.internal.DecryptionHandler.<init>(DecryptionHandler.java:96)
	at com.amazonaws.encryptionsdk.internal.DecryptionHandler.create(DecryptionHandler.java:185)
	at com.amazonaws.encryptionsdk.AwsCrypto.decryptData(AwsCrypto.java:380)
	at com.amazonaws.encryptionsdk.AwsCrypto.decryptData(AwsCrypto.java:357)
	at com.amazonaws.encryptionsdk.AwsCrypto.decryptString(AwsCrypto.java:430)
	at com.amazonaws.encryptionsdk.AwsCrypto.decryptString(AwsCrypto.java:412)
	at service.SecretsService.decryptConnectionSecret(SecretsService.java:158)

The secrets encrypted are of 255 chars max and we are using the version 1.3.5 of the SDK.
Looking into the stack trace it seems that we are getting a timeout on the AmazonHttpClient. If that its the case, is there a way to give this request more time though the encryption SDK or some environment variable?

Remove frame-size block-length restriction

While we may need to support non-stream ciphers at some point, currently our only bulk cipher is AES-GCM which has no block size restrictions. Thus, we can (and should) remove the restriction that our frame-sizes be a multiple of 16.

https://github.com/awslabs/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java#L140

This change should be completely backwards compatible as this restriction is only enforced on the encrypt path and not the decrypt path. As part of this change, backwards compatibility will be manually tested.

Additionally, this task will also be completed in aws-encryption-sdk-python

Maven jar is not up to date

I need to get a KmsMasterKeyProvider based on an alias, not an ARN. I am unable to get this to work with the Maven jar (which goes back to March 2018) but I see a fix was put in for this issue in April 2018. Can you guys push the latest code up to Maven? Otherwise I can build it myself, obviously, but I'd prefer to stay in sync with you.

KmsMasterKeyProvider regionalClientSupplier_ does not appear to be getting set correctly by default

When a KmsMasterKeyProvider is constructed using the default builder[1] and is then used to attempt to decrypt a ciphertext message from another region, the decrypt call fails with this error[2].

It appears that something is not connecting with the default supplier in build()[3].

[1] KmsMasterKeyProvider.builder().build()
[2]

throw new AwsCryptoException("Can't use keys from region " + regionName_);

[3]
public KmsMasterKeyProvider build() {
// If we don't have a default region, we need to check that all key IDs will be usable
if (defaultRegion_ == null) {
for (String keyId : keyIds_) {
if (parseRegionfromKeyArn(keyId) == null) {
throw new AwsCryptoException("Can't use non-ARN key identifiers or aliases when " +
"no default region is set");
}
}
}
RegionalClientSupplier supplier = clientFactory();
return new KmsMasterKeyProvider(supplier, defaultRegion_, keyIds_, emptyList(), false);
}

Expose additional information for metrics

Specifically timing & encrypt/decrypt success/failure rates when using multiple KMS providers that may be skipped over automatically during each operation.

This will help from an operations standpoint when latency spikes up or debugging if we're seeing increased failures.

Unfortunately I'm not terribly sure how this would look with the DefaultCryptoMaterialsManager in practice. Callbacks you can register?

As an example, we wrote our own multi-region encryption materials manager and we've tried to add these metrics tagged with the region we're going to. Since we're using a key alias, we can parse the region out of the provider information string easily enough when it's successful (exactly like you do in the KmsMasterKeyProvider), but getting the region from AwsCryptoException (for encryption errors) or AWSKMSException (for data key generation errors) has proven to be a painful parsing exercise :) Having the region easily accessible on each exception would be quite helpful for this purpose.

Thanks!

Illegal Key Size exception

Hi! I'm getting the exception below in a job in CircleCI when running some unit tests:

com.amazonaws.encryptionsdk.exception.AwsCryptoException: java.security.InvalidKeyException: Illegal key size, took 0.267 sec
    at com.amazonaws.encryptionsdk.internal.CipherHandler.cipherData(CipherHandler.java:78)
    at com.amazonaws.encryptionsdk.internal.EncryptionHandler.computeHeaderTag(EncryptionHandler.java:373)
    at com.amazonaws.encryptionsdk.internal.EncryptionHandler.signCiphertextHeaders(EncryptionHandler.java:401)
    at com.amazonaws.encryptionsdk.internal.EncryptionHandler.<init>(EncryptionHandler.java:135)
    at com.amazonaws.encryptionsdk.AwsCrypto.encryptData(AwsCrypto.java:248)
    at com.amazonaws.encryptionsdk.AwsCrypto.encryptString(AwsCrypto.java:305)
    at com.amazonaws.encryptionsdk.AwsCrypto.encryptString(AwsCrypto.java:293)
    at com.amazonaws.encryptionsdk.AwsCrypto.encryptString(AwsCrypto.java:320)
    at <local_code>
    ...
Caused by: java.security.InvalidKeyException: Illegal key size
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
    at javax.crypto.Cipher.implInit(Cipher.java:805)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
    at javax.crypto.Cipher.init(Cipher.java:1396)
    at javax.crypto.Cipher.init(Cipher.java:1327)
    at com.amazonaws.encryptionsdk.internal.CipherHandler.cipherData(CipherHandler.java:73)
    ... 71 more

That job is running the docker image openjdk:8-jdk and the version used of this SDK is 1.3.5.

The only reference I've found is #1, where the fix seems to be installing JCE but README points out it is needed when running Oracle JDK.

Additionally, I have another job running in Circle for the same project using the same configuration, at least it seems so, and there tests are working fine.

Define constraints on JceMasterKey RSA wrapping algorithms

Problem

JceMasterKey is very poorly constrained when using RSA master keys. The current implementation only verifies that the wrapping algorithm name starts with "RSA/ECB/", leaving the padding algorithm open to whatever any given JCE provider makes available.

aws/aws-encryption-sdk-python#56

Without providing some constraints around the permitted padding algorithms for RSA master keys, we cannot guarantee full compatibility between this and any other implementation.

Proposed Solution

We should constrain the allowed padding algorithms to a whitelisted set. This does hold the risk of breaking existing usage if anyone is using an unusual padding algorithm not on this list.

Allow

Consider for future

  • RSA/ECB/OAEPWithSHA-224AndMGF1Padding - Better than SHA1, but based on consultation with algorithms team we should leave it off unless we receive requests for it.

Alternate Solution

Alternately, we could simply document the above as officially supported padding algorithms and raise a warning if an unsupported padding algorithm is used. I like this less from a "keep the foot-guns locked away" perspective, but it is the safer option considering how long the existing implementation has been in the wild.

Support for other algorithms (other than AES/GCM/NoPadding) when using JceMasterKey

https://github.com/awslabs/aws-encryption-sdk-java/blob/7d5ab6eef428364286c50b969ef89766be6207ee/src/main/java/com/amazonaws/encryptionsdk/jce/JceMasterKey.java#L76

Trying to understand this library a bit better... Would it be possible to support other encryption algorithms other than just AES/GCM/NoPadding for symmetric key encryption using the JceMasterKey? If not, why not?

For my master key, I would prefer an algorithm that would allow us to encrypt tons of data before rotating (AES/GCM is recommended to only encrypt a total of ~64GB of data with a single key, which in this case of encrypting 128 bit data keys, would be ~4 billion encryption operations)

refactor examples into its own module

per conversations at #6 (comment), creating this issue.

aws-encryption-sdk-java\
->    pom.xml   //artifact name for this can be aws-encryption-sdk-java-parent
->    aws-encryption-sdk-java-core
        -> pom.xml, src   //this generates aws-encryption-sdk-java artifact
->    aws-encryption-sdk-java-examples
       -> pom.xml, src  //this generates aws-encryption-sdk-java-examples artifact

Guys put your feedbacks/proposals in the comments section.

Ensure all transformations are handled in a case-insensitive way

The JCE/JCA defines transformations as being case-insensitive, though there are standardized capitalizations which are almost always used. We must check our code (especially JceMasterKey) to ensure that we handle transformations with irregular capitalization.

KMS access

It's a question, rather than an issue. When using KmsMasterKeyProvider, does it actually call KMS service each time you encrypt / decrypt data? I walked through the Concepts and Architecture documents but I'm a bit confused about the network calls AWS Encryption SDK will make when combined with AWS KMS.

Could you elaborate it more using the String Example?

Does it actually access KMS for the master key decryption when encryptString is called?

Could you somehow use KmsMasterKeyProvider as singleton and re-use the same master key for multiple encryptions?

Test failures

When I check this out clean and run mvn install, I get the following test failures:

Tests in error:
  encryptDecryptWithAllAlgos(com.amazonaws.encryptionsdk.internal.CipherHandlerTest): java.security.InvalidKeyException: Illegal key size
  tamperCiphertext(com.amazonaws.encryptionsdk.internal.CipherHandlerTest): Unexpected exception, expected<com.amazonaws.encryptionsdk.exception.BadCiphertextException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  headerIntegerityFailure(com.amazonaws.encryptionsdk.internal.DecryptionHandlerTest): Unexpected exception, expected<com.amazonaws.encryptionsdk.exception.BadCiphertextException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  invalidVersion(com.amazonaws.encryptionsdk.internal.DecryptionHandlerTest): Unexpected exception, expected<com.amazonaws.encryptionsdk.exception.BadCiphertextException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  singleKeyPkcs1(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  singleKeyOaepSha1(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  singleKeyOaepSha256(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  multipleKeys(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  encryptOnly(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): Unexpected exception, expected<com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  escrowAndSymmetric(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  escrowAndSymmetricSecondProvider(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  escrowCase(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  keystoreAndRawProvider(com.amazonaws.encryptionsdk.jce.KeyStoreProviderTest): java.security.InvalidKeyException: Illegal key size
  testMultipleJceKeys(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  testMultipleJceKeysSingleDecrypt(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  testMultipleKmsKeys(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  testMultipleKmsKeysSingleDecrypt(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  testMultipleRegionKmsKeys(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  testMixedKeys(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  testMixedKeysSingleDecrypt(com.amazonaws.encryptionsdk.multi.MultipleMasterKeyTest): java.security.InvalidKeyException: Illegal key size
  encryptDecrypt(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptDecryptWithBadSignature(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptDecryptWithParsedCiphertext(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  estimateCiphertextSize(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  estimateCiphertextSizeWithoutEncContext(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptDecryptWithoutEncContext(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptDecryptString(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptDecryptStringWithoutEncContext(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptBytesDecryptString(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  encryptStringDecryptBytes(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  emptyEncryptionContext(com.amazonawsencryptionsdk.AwsCryptoTest): java.security.InvalidKeyException: Illegal key size
  nullPlaintextEncrypt(com.amazonawsencryptionsdk.AwsCryptoTest): Unexpected exception, expected<java.lang.NullPointerException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  nullEncryptingInputStream(com.amazonawsencryptionsdk.AwsCryptoTest): Unexpected exception, expected<java.lang.NullPointerException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  nullEncryptingOutputStream(com.amazonawsencryptionsdk.AwsCryptoTest): Unexpected exception, expected<java.lang.NullPointerException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  encryptDecrypt(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  doEncryptDecryptWithoutEncContext(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  encryptAPIComptability(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  decryptAPIComptability(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  outputStreamComptability(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  singleByteRead(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  nullReadBuffer(com.amazonawsencryptionsdk.CryptoInputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  nullReadBuffer2(com.amazonawsencryptionsdk.CryptoInputStreamTest): Unexpected exception, expected<java.lang.NullPointerException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  zeroReadLen(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  negativeReadLen(com.amazonawsencryptionsdk.CryptoInputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  negativeReadOffset(com.amazonawsencryptionsdk.CryptoInputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  invalidReadOffset(com.amazonawsencryptionsdk.CryptoInputStreamTest): Unexpected exception, expected<java.lang.ArrayIndexOutOfBoundsException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  noOpStream(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  checkEncContext(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  checkKeyId(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  checkAvailable(com.amazonawsencryptionsdk.CryptoInputStreamTest): java.security.InvalidKeyException: Illegal key size
  encryptDecrypt(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  doEncryptDecryptWithoutEncContext(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  encryptAPIComptability(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  decryptAPIComptability(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  checkEncContext(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  checkKeyId(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  singleByteWrite(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  inputStreamComptability(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size
  nullWrite(com.amazonawsencryptionsdk.CryptoOutputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  nullWrite2(com.amazonawsencryptionsdk.CryptoOutputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  negativeWriteLen(com.amazonawsencryptionsdk.CryptoOutputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  negativeWriteOffset(com.amazonawsencryptionsdk.CryptoOutputStreamTest): Unexpected exception, expected<java.lang.IllegalArgumentException> but was<com.amazonaws.encryptionsdk.exception.AwsCryptoException>
  checkInvalidValues(com.amazonawsencryptionsdk.CryptoOutputStreamTest): java.security.InvalidKeyException: Illegal key size

Tests run: 189, Failures: 0, Errors: 63, Skipped: 0

Fix maven plugin versions

[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.amazonaws:aws-encryption-sdk-java:jar:1.3.6
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-source-plugin is missing.
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-deploy-plugin is missing.
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.```

crypting Kinesis record for .NET

Hi,
I contacted AWS support and they told me you could maybe help. If I'm at the wrong location just tell me where to post this message.
I'm looking for .Net encryption library for Kinesis' PutRecord/PutRecords. Would you have any idea how to get information for creation of such a library ?
Thank you

jce KeyStoreProvider fails to properly decrypt data keys

The JCE KeyStoreProvider is using the encrypted data key provider info to look up keys in the KeyStore, but the provider info is the combination of the key id and the wrapping data. As a result, the key lookup always fails and the data key can not be decrypted. This is for the case of symmetric keys.

-- setting up the provider info, contains the key id and the wrapping data
-- from encryptRawKey in jce/JceMasterKey

final byte[] provInfo = new byte[keyIdBytes_.length + wData.extraInfo.length];
System.arraycopy(keyIdBytes_, 0, provInfo, 0, keyIdBytes_.length);
System.arraycopy(wData.extraInfo, 0, provInfo, keyIdBytes_.length, wData.extraInfo.length);
return new DataKey<>(key, encryptedKey, provInfo, this);

-- trying to find a key in the keystore; will not find it since 'alias' contains more than the key id
-- from decryptDataKey in jce/KeyStoreProvider

final String alias = new String(edk.getProviderInformation(), StandardCharsets.UTF_8);
if (keystore_.isKeyEntry(alias)) {
  final DataKey<JceMasterKey> result = getMasterKey(alias).decryptDataKey(algorithm,
                        Collections.singletonList(edk),
                        encryptionContext);
  if (result != null) {
    return result;
  }
}

Not quite sure of the fix, need to get the size of the key id or wrapping data in order to properly extract the key id from the provider info, but it's not available within KeyStoreProvider.

CIRCULAR REFERENCE:com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys

We are seeing the following error when attempting to run a Lambda on AWS. This exact Lambda was running fine for us, then we wanted to reuse it and updated some of the keys and field/class names then we started getting an encryption key exception.

We have attempted to regenerate the key and the issue persists. Can you point us in any direction to begin debugging this?

Caused by: com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys
at com.amazonaws.encryptionsdk.MasterKeyProvider.buildCannotDecryptDksException(MasterKeyProvider.java:106)
at com.amazonaws.encryptionsdk.multi.MultipleProviderFactory$MultiProvider.decryptDataKey(MultipleProviderFactory.java:158)
at com.amazonaws.encryptionsdk.internal.DecryptionHandler.getDataKey(DecryptionHandler.java:329)
at com.amazonaws.encryptionsdk.internal.DecryptionHandler.readHeaderFields(DecryptionHandler.java:382)
at com.amazonaws.encryptionsdk.internal.DecryptionHandler.<init>(DecryptionHandler.java:124)
at com.amazonaws.encryptionsdk.AwsCrypto.decryptData(AwsCrypto.java:242)
at com.amazonaws.encryptionsdk.AwsCrypto.decryptData(AwsCrypto.java:233)
at com.nike.webhooks.common.security.KmsEncryptDecrypt.decrypt(KmsEncryptDecrypt.java:37)
at com.nike.webhooks.common.repository.EventConverter.unconvert(EventConverter.java:55)
at com.nike.webhooks.common.repository.EventConverter.unconvert(EventConverter.java:18)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.unconvert(DynamoDBTypeConverter.java:109)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$NullSafeConverter.unconvert(DynamoDBTypeConverter.java:128)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$ExtendedConverter.unconvert(DynamoDBTypeConverter.java:88)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvert(DynamoDBMapperFieldModel.java:146)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvertAndSet(DynamoDBMapperFieldModel.java:164)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.unconvert(DynamoDBMapperTableModel.java:267)
... 18 more
Suppressed: com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys
at com.amazonaws.encryptionsdk.MasterKeyProvider.buildCannotDecryptDksException(MasterKeyProvider.java:103)
at com.amazonaws.encryptionsdk.kms.KmsMasterKey.decryptDataKey(KmsMasterKey.java:182)
at com.amazonaws.encryptionsdk.multi.MultipleProviderFactory$MultiProvider.decryptDataKey(MultipleProviderFactory.java:150)
... 32 more
[CIRCULAR REFERENCE:com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys]

Encryption context compatibility with AWS CLI

There appears to be a compatibility issue between the aws CLI and the encryption sdk around the way that encryption context is formatted. This makes combining decryption of sensitive data in java apps difficult to integrate with many dev ops automation tools.

encrypting a secret on the command line
aws kms encrypt --key-id --plaintext "1!2@3#4$5%6^7&8*9(0)-_=+" --query CiphertextBlob --encryption-context key=value --output text | base64 -d > /tmp/encrypted

and decrypting it in java

final Map<String, String> context = Collections.singletonMap("key", "value");
final CryptoResult<String, KmsMasterKey> decryptResult = crypto.decryptString(prov, ciphertext);

will give you a cipher text error because the encryption contexts don't match.

Is there a way to make this work that I'm missing or is a local java tool just for encrypting strings going to be required? Alternatively I could look at overriding the sdk serialization function to provide a cli compatible context serialization.

Thanks.

Jason

Support of Bouncy Castle JCE is not implementing yet

looks like here is chipper from Java JCE only not from BC JCE.
How I can use Cipher from BC?
aws-encryption-sdk-java/src/main/java/com/amazonaws/encryptionsdk/internal/CipherHandler.java
private static Cipher buildCipherObject(final CryptoAlgorithm alg) {
try {
// Right now, just GCM is supported
return Cipher.getInstance("AES/GCM/NoPadding");
} catch (final GeneralSecurityException ex) {
throw new IllegalStateException("Java does not support the requested algorithm", ex);
}
}

KmsMasterKeyProvider region should default to the value found in ~/.aws/config

When KmsMasterKeyProvider is constructed without a region it usesRegion.getRegion(Regions.DEFAULT_REGION) as seen below:

public KmsMasterKeyProvider(final AWSCredentials creds) {
    this(new StaticCredentialsProvider(creds), Region.getRegion(Regions.DEFAULT_REGION), new ClientConfiguration(),
            Collections.<String> emptyList());
}

In boto3, if a region is not specified, it tries to use the value for region found in ~/.aws/config. http://boto3.readthedocs.io/en/latest/guide/configuration.html#configuration-file

In my opinion, the AWS Encryption SDK should behave similarly, falling back on Regions.DEFAULT_REGION if ~/.aws/config cannot be used.

Support MultiProvider Encrypt when not all providers are available

First off - what a great library. This solves many problems that a developer would have otherwise needed to handle on their own. Thank you!

We are looking to use this library to provide Multi-Region KMS encrypt and decrypt operations, where if any KMS service in any single region is down, we are not down. This works today for Decrypt operations which is awesome, but not Encrypt operations - all providers must be available to encrypt data. In a sense, what one was attempting to achieve in reducing the risk of an outage by leveraging two different KMS’s (for instance), you actually increase your outage risk on encrypt operations because if a single KMS provider is down in any region, you are down for encrypts.

I would like to see the MultiProviderFactory have some construction options where I can specify the minimum number of providers (or a quorum) that must be available for encrypt to succeed - or something of the sort. Leaving it configurable allows the product to decide how much risk to take on (for encrypting data that can not be decrypted later by every single provider in the event providers are not available)

AWSKMSException: The security token included in the request is invalid.

When running this sample code:

public class InvalidSecurityToken {

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
        final String accessKey = requiredEnvVar("ACCESS_KEY");
        final String secretKey = requiredEnvVar("SECRET_KEY");
        final String customerMasterKey = requiredEnvVar("CMK");
        final String region = requiredEnvVar("REGION");

        final AwsCrypto awsCrypto = new AwsCrypto();

        final KmsMasterKeyProvider masterKeyProvider = new KmsMasterKeyProvider(
                new BasicAWSCredentials(accessKey, secretKey),
                customerMasterKey
        );

        masterKeyProvider.setRegion(Region.getRegion(Regions.fromName(region)));

        final String plainText = "Hello, World!";

        final Map<String, String> context = Collections.singletonMap("Context", "Bug Report");

        final byte[] encryptedResult = awsCrypto.encryptData(
                masterKeyProvider,
                plainText.getBytes(),
                context
        ).getResult();

        System.out.println(Base64.getEncoder().encodeToString(encryptedResult));
    }

    private static String requiredEnvVar(String name) {
        final String envVar = System.getenv(name);

        if (envVar == null || envVar.trim().length() == 0) {
            throw new RuntimeException("Missing environment variable: " + name);
        }

        System.out.printf("%s = %s\n", name, envVar);

        return envVar;
    }

}

I am getting the following error:

Exception in thread "main" com.amazonaws.services.kms.model.AWSKMSException: The security token included in the request is invalid. (Service: AWSKMS; Status Code: 400; Error Code: UnrecognizedClientException; Request ID: b3624a4d-6795-11e6-9331-fd581625bf3e)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1386)
    ...

The request ID (b3624a4d-6795-11e6-9331-fd581625bf3e) might be handy to figure out if I am doing something wrong on my end or if this is a bug in the SDK.

  • For CMK, I tried both an alias (e.g. alias/foo) as well as an ARN. The CMK is already created and the used ACCESS/SECRET key combo have permission to use it.
  • And the region I am using in this scenario is ap-southeast-2.

I have attached a small app that can be used to reproduce the issue:

bugreport.zip

0.0.1-SNAPSHOT release

I want to use aws-encryption-sdk in my project with currently available functionality. So I want to stick to 0.0.1 and update only intentionally by updating version. Therefore could you please provide 0.0.1 and switch development to 0.0.2-SNAPSHOT if possible

MasterKeyProvider.decryptDataKey(...) is called twice

In AwsCrypto. decryptData(...), the call to decryptDataKey is called twice.
1> at https://github.com/awslabs/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java#L242
where DecryptHandler is trying to read header and decrypts the data key.

2> at https://github.com/awslabs/aws-encryption-sdk-java/blob/master/src/main/java/com/amazonaws/encryptionsdk/AwsCrypto.java#L248
the read header method is again called and hence trying to decrypt the same data key.

AWS SDK for Java 2.0 compatibility

Problem

The AWS SDK for Java 2.0 will involve a significant change in that library's API and namespaces. We need to determine the right approach to ensuring compatibility with both the 1.0 and 2.0 libraries without incurring too many issues with code duplication.

Exception in thread "main" com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys

I am trying to encrypt and decrypt the file using this SDK and i get this error while decrypting it. I am using MultipleProviderFactory.buildMultiProvider() to build the MasterKeyProvider. The same code works fine if i use KmsMasterKeyProvider.

The exception trace is

Exception in thread "main" com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys
at com.amazonaws.encryptionsdk.MasterKeyProvider.buildCannotDecryptDksException(MasterKeyProvider.java:106)
at com.amazonaws.encryptionsdk.multi.MultipleProviderFactory$MultiProvider.decryptDataKey(MultipleProviderFactory.java:158)
at com.amazonaws.encryptionsdk.internal.DecryptionHandler.getDataKey(DecryptionHandler.java:329)
at com.amazonaws.encryptionsdk.internal.DecryptionHandler.readHeaderFields(DecryptionHandler.java:382)
at com.amazonaws.encryptionsdk.internal.DecryptionHandler.(DecryptionHandler.java:124)
at com.amazonaws.encryptionsdk.AwsCrypto.decryptData(AwsCrypto.java:242)
at com.amazonaws.encryptionsdk.AwsCrypto.decryptData(AwsCrypto.java:233)
at com.shn.api.kms.poc.S3EncryptExample.decryptUsingProvider(S3EncryptExample.java:148)
at com.shn.api.kms.poc.S3EncryptExample.main(S3EncryptExample.java:195)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Suppressed: com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys
at com.amazonaws.encryptionsdk.MasterKeyProvider.buildCannotDecryptDksException(MasterKeyProvider.java:103)
at com.amazonaws.encryptionsdk.kms.KmsMasterKey.decryptDataKey(KmsMasterKey.java:182)
at com.amazonaws.encryptionsdk.multi.MultipleProviderFactory$MultiProvider.decryptDataKey(MultipleProviderFactory.java:150)
... 12 more
[CIRCULAR REFERENCE:com.amazonaws.encryptionsdk.exception.CannotUnwrapDataKeyException: Unable to decrypt any data keys]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.