/// <summary> /// Attempt to generate a KMS datakey using the first successful response using a sorted dictionary of available KMS clients. /// </summary> /// <param name="sortedRegionToArnAndClientDictionary"> A sorted dictionary mapping regions and their arns and kms clients</param> /// <param name="dateKeyKeyId">The KMS arn used to generate the data key</param> /// <returns>A GenerateDataKeyResult object that contains the plain text key and the ciphertext for that key</returns> /// <exception cref="KmsException">Throw an exception if we're unable to generate a datakey in any AWS region</exception> internal virtual GenerateDataKeyResult GenerateDataKey(OrderedDictionary sortedRegionToArnAndClientDictionary, out string dateKeyKeyId) { foreach (DictionaryEntry regionToArnAndClient in sortedRegionToArnAndClientDictionary) { try { TimerOptions generateDataKeyTimerOptions = new TimerOptions { Name = MetricsUtil.AelMetricsPrefix + ".kms.aws.generatedatakey." + regionToArnAndClient.Key }; using (MetricsUtil.MetricsInstance.Measure.Timer.Time(generateDataKeyTimerOptions)) { IAmazonKeyManagementService client = ((AwsKmsArnClient)regionToArnAndClient.Value).AwsKmsClient; string keyIdForDataKeyGeneration = ((AwsKmsArnClient)regionToArnAndClient.Value).Arn; GenerateDataKeyResult generateDataKeyResult = client.GenerateDataKey( keyIdForDataKeyGeneration, null, DataKeySpec.AES_256); dateKeyKeyId = keyIdForDataKeyGeneration; return(generateDataKeyResult); } } catch (AmazonServiceException e) { Logger.LogWarning(e, "Failed to generate data key via region {region}, trying next region", regionToArnAndClient.Key); // TODO Consider adding notification/CW alert } } throw new KmsException("could not successfully generate data key using any regions"); }
/// <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 EncryptionInstructions GenerateInstructionsForKMSMaterialsV2(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 = kmsClient.GenerateDataKey(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec); 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}"); } }
public void GenerateKey(int keyBits, out byte[] key, out byte[] encryptedKey, IDictionary <string, string> context) { DataKeySpec keySpec; if (keyBits == 128) { keySpec = DataKeySpec.AES_128; } else if (keyBits == 256) { keySpec = DataKeySpec.AES_256; } else { throw new ArgumentException("only 128 and 256 bit keys are supported", "keyBits"); } var request = new GenerateDataKeyRequest { KeyId = _keyId, KeySpec = keySpec, EncryptionContext = AsDictionary(context) }; GenerateDataKeyResponse response = _client.GenerateDataKey(request); key = response.Plaintext.ToArray(); encryptedKey = response.CiphertextBlob.ToArray(); }
/// <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 EncryptionInstructions GenerateInstructionsForKMSMaterials(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 = kmsClient.GenerateDataKey(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec); return(new EncryptionInstructions(materials.MaterialsDescription, generateDataKeyResult.KeyPlaintext, generateDataKeyResult.KeyCiphertext, iv, XAmzWrapAlgKmsValue, XAmzAesCbcPaddingCekAlgValue)); }
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; } }
public GenerateDataKeyResult GenerateDataKey(string keyId, Dictionary <string, string> encryptionContext, string keySpec) { return(_service.GenerateDataKey(keyId, encryptionContext, keySpec)); }