Example #1
0
        /// <summary>
        /// Generates a data key for the specified master key. This will return both
        /// the plaintext key that you can use for encryption/decryption and the
        /// same key as protected by the master key.
        /// </summary>
        /// <param name="keyId">The identifier of the key we should use to generate and protect the data key.</param>
        /// <returns>Result containing the plaintext representation of the generated data key
        /// which can be used for encryption/decryption, an encrypted version of the
        /// data key encrypted by the master key and the ID of the key that was used.</returns>
        /// <exception cref="KeyManagementServiceUnavailableException"></exception>
        public GenerateDataKeyResult GenerateDataKey(string keyId)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("AwsKmsKeyManager");
            }

            ValidateMasterKey(keyId);

            var res = RetryPolicy.ExecuteAndCapture(() =>
            {
                var req = new GenerateDataKeyRequest
                {
                    KeyId   = keyId,
                    KeySpec = DataKeySpec.AES_128
                };

                var t = _client.GenerateDataKeyAsync(req);
                t.ConfigureAwait(false);
                return(t.GetAwaiter().GetResult());
            });

            ValidateResponse(res);

            var result = (GenerateDataKeyResponse)res.Result;

            return(new GenerateDataKeyResult
            {
                KeyId = keyId,
                CipherTextKey = result.CiphertextBlob.ToArray(),
                PlainTextKey = result.Plaintext.ToArray()
            });
        }
Example #2
0
        /// <summary>
        /// Generates an instruction that will be used to encrypt an object
        /// using materials with the KMSKeyID set.
        /// </summary>
        /// <param name="kmsClient">
        /// Used to call KMS to generate a data key.
        /// </param>
        /// <param name="materials">
        /// The encryption materials to be used to encrypt and decrypt data.
        /// </param>
        /// <returns>
        /// The instruction that will be used to encrypt an object.
        /// </returns>
        internal static async System.Threading.Tasks.Task <EncryptionInstructions> GenerateInstructionsForKMSMaterialsV2Async(IAmazonKeyManagementService kmsClient,
                                                                                                                              EncryptionMaterialsV2 materials)
        {
            if (materials.KMSKeyID == null)
            {
                throw new ArgumentNullException(nameof(materials.KMSKeyID), KmsKeyIdNullMessage);
            }

            switch (materials.KmsType)
            {
            case KmsType.KmsContext:
            {
                var nonce = new byte[DefaultNonceSize];

                // Generate nonce, and get both the key and the encrypted key from KMS.
                RandomNumberGenerator.Create().GetBytes(nonce);
                var result = await kmsClient.GenerateDataKeyAsync(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec).ConfigureAwait(false);

                var instructions = new EncryptionInstructions(materials.MaterialsDescription, result.KeyPlaintext, result.KeyCiphertext, nonce,
                                                              XAmzWrapAlgKmsContextValue, XAmzAesGcmCekAlgValue);
                return(instructions);
            }

            default:
                throw new NotSupportedException($"{materials.KmsType} is not supported for KMS Key Id {materials.KMSKeyID}");
            }
        }
Example #3
0
        private async Task <(MemoryStream dataKey, string encryptedDataKey)> GenerateEncryptionKey(string keyAlias)
        {
            GenerateDataKeyResponse generateKeyResponse = null;

            try
            {
                generateKeyResponse = await mAmazonKeyManagementService.GenerateDataKeyAsync(new GenerateDataKeyRequest { KeyId = keyAlias, KeySpec = "AES_256" });
            }
            catch (NotFoundException)
            {
                await GenerateMasterKey(keyAlias);

                generateKeyResponse = await mAmazonKeyManagementService.GenerateDataKeyAsync(new GenerateDataKeyRequest { KeyId = keyAlias, KeySpec = "AES_256" });
            }

            if (generateKeyResponse.HttpStatusCode != HttpStatusCode.OK)
            {
                throw new Exception($"Couldn't generate encryption key for {keyAlias}");
            }

            return(generateKeyResponse.Plaintext, ConvertMemoryStreamToBase64String(generateKeyResponse.CiphertextBlob));
        }
Example #4
0
        /// <summary>
        /// Generates an instruction that will be used to encrypt an object
        /// using materials with the KMSKeyID set.
        /// </summary>
        /// <param name="kmsClient">
        /// Used to call KMS to generate a data key.
        /// </param>
        /// <param name="materials">
        /// The encryption materials to be used to encrypt and decrypt data.
        /// </param>
        /// <returns>
        /// The instruction that will be used to encrypt an object.
        /// </returns>
        internal static async System.Threading.Tasks.Task <EncryptionInstructions> GenerateInstructionsForKMSMaterialsAsync(
            IAmazonKeyManagementService kmsClient, EncryptionMaterials materials)
        {
            if (materials.KMSKeyID == null)
            {
                throw new ArgumentNullException(nameof(materials.KMSKeyID), KmsKeyIdNullMessage);
            }

            var iv = new byte[IVLength];

            // Generate IV, and get both the key and the encrypted key from KMS.
            RandomNumberGenerator.Create().GetBytes(iv);
            var generateDataKeyResult = await kmsClient.GenerateDataKeyAsync(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec).ConfigureAwait(false);

            return(new EncryptionInstructions(materials.MaterialsDescription, generateDataKeyResult.KeyPlaintext, generateDataKeyResult.KeyCiphertext, iv,
                                              XAmzWrapAlgKmsValue, XAmzAesCbcPaddingCekAlgValue));
        }
Example #5
0
        public async Task <CryptoData> EncryptWithKey(string data)
        {
            var keyReq = new GenerateDataKeyRequest
            {
                KeyId   = this.keyId,
                KeySpec = DataKeySpec.AES_256
            };
            var dataKeyResponse = await client.GenerateDataKeyAsync(keyReq);

            var key          = GetBase64StringFromStream(dataKeyResponse.CiphertextBlob);
            var plainTextKey = GetBase64StringFromStream(dataKeyResponse.Plaintext);
            var protector    = dataProtectionProvider.CreateProtector(plainTextKey);
            var result       = protector.Protect(data);

            return(new CryptoData
            {
                Encrypted = result,
                Key = key
            });
        }
Example #6
0
        private async Task <KeyDataResponse> GenerateKeyData(string keyId, Dictionary <string, string> encryptionContext)
        {
            try
            {
                var kmsResponse = await _amazonKeyManagementService.GenerateDataKeyAsync(new GenerateDataKeyRequest
                {
                    EncryptionContext = encryptionContext,
                    KeyId             = keyId,
                    NumberOfBytes     = 64
                }).ConfigureAwait(false);

                return(new KeyDataResponse
                {
                    CiphertextBlob = kmsResponse.CiphertextBlob.ToArray(),
                    Plaintext = kmsResponse.Plaintext.ToArray()
                });
            }
            catch (Exception e)
            {
                throw new CredstashException("Encryption Key Generation error", e);
            }
        }
Example #7
0
 private Amazon.KeyManagementService.Model.GenerateDataKeyResponse CallAWSServiceOperation(IAmazonKeyManagementService client, Amazon.KeyManagementService.Model.GenerateDataKeyRequest request)
 {
     Utils.Common.WriteVerboseEndpointMessage(this, client.Config, "AWS Key Management Service", "GenerateDataKey");
     try
     {
         #if DESKTOP
         return(client.GenerateDataKey(request));
         #elif CORECLR
         return(client.GenerateDataKeyAsync(request).GetAwaiter().GetResult());
         #else
                 #error "Unknown build edition"
         #endif
     }
     catch (AmazonServiceException exc)
     {
         var webException = exc.InnerException as System.Net.WebException;
         if (webException != null)
         {
             throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException);
         }
         throw;
     }
 }