/// <summary> /// Unmarshaller the response from the service to the response class. /// </summary> /// <param name="context"></param> /// <returns></returns> public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context) { GenerateDataKeyResponse response = new GenerateDataKeyResponse(); context.Read(); int targetDepth = context.CurrentDepth; while (context.ReadAtDepth(targetDepth)) { if (context.TestExpression("CiphertextBlob", targetDepth)) { var unmarshaller = MemoryStreamUnmarshaller.Instance; response.CiphertextBlob = unmarshaller.Unmarshall(context); continue; } if (context.TestExpression("KeyId", targetDepth)) { var unmarshaller = StringUnmarshaller.Instance; response.KeyId = unmarshaller.Unmarshall(context); continue; } if (context.TestExpression("Plaintext", targetDepth)) { var unmarshaller = MemoryStreamUnmarshaller.Instance; response.Plaintext = unmarshaller.Unmarshall(context); continue; } } return(response); }
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(); }
public void ServiceReturnsFailCode() { _result = new GenerateDataKeyResponse { HttpStatusCode = HttpStatusCode.InternalServerError }; KmsService.GenerateDataKeyAsync(Arg.Any <GenerateDataKeyRequest>()).Returns(_result); }
public void ServiceReturnsFailCode() { _result = new GenerateDataKeyResponse { HttpStatusCode = HttpStatusCode.ServiceUnavailable }; KmsService.GenerateDataKeyAsync(Arg.Any <GenerateDataKeyRequest>()).Returns(_result); }
public static GenerateDataKeyResponse Unmarshall(UnmarshallerContext context) { GenerateDataKeyResponse generateDataKeyResponse = new GenerateDataKeyResponse(); generateDataKeyResponse.HttpResponse = context.HttpResponse; generateDataKeyResponse.CiphertextBlob = context.StringValue("GenerateDataKey.CiphertextBlob"); generateDataKeyResponse.KeyId = context.StringValue("GenerateDataKey.KeyId"); generateDataKeyResponse.Plaintext = context.StringValue("GenerateDataKey.Plaintext"); generateDataKeyResponse.RequestId = context.StringValue("GenerateDataKey.RequestId"); return(generateDataKeyResponse); }
private GenerateDataKeyResponse SanitizedResponse(GenerateDataKeyResponse response) { if (response == null) { return(response); } response.CiphertextBlob = null; response.Plaintext = null; response.ResponseMetadata = null; return(response); }
private SecureString GetDataKeyFromKms(string application, string tenantId, string keyIdentifier) { using (var scope = new ProfileContext($"Generating new crypto key using kms for {application} {tenantId}")) { GenerateDataKeyRequest request = null; GenerateDataKeyResponse response = null; bool isSuccess = false; try { var client = _kmsClientFactory.GetGlobalClient(); request = GetGenerateDataKeyRequest(application, tenantId, keyIdentifier); var waitHandle = new ManualResetEvent(false); Task.Factory.StartNew(async() => { try { response = await client.GenerateDataKeyAsync(request); } catch (Exception ex) { Platform.Common.ExceptionPolicy.HandleException(ex, Constants.LogOnlyPolicy); throw Errors.ServerSide.KMSCommunicationError(); } finally { waitHandle.Set(); } }); waitHandle.WaitOne(); if (response == null || response.HttpStatusCode != HttpStatusCode.OK) { throw Errors.ServerSide.KMSCommunicationError(); } //CiperTextBlob is Base64-encoded binary data _cryptoKeyStore.Add(application, tenantId, keyIdentifier, response.CiphertextBlob.ToArray()); isSuccess = true; //PlaintText is Base64-encoded binary data return(ConvertStreamToSecureString(response.Plaintext)); } finally { LogRQRS(request, SanitizedResponse(response), application, tenantId, "aws_kms_provider", "generate_datakey", isSuccess); } } }
public static async Task <byte[]> EncryptData(string toEncrypt, AccountCredentials credentials, string region, CancellationToken token = default) { try { var jsonMemStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(toEncrypt ?? "")); var cmk = credentials.cmk; var kmsClient = new AmazonKeyManagementServiceClient(credentials.AWSCredentials, RegionEndpoint.GetBySystemName(region)); kmsClient.ExceptionEvent += KmsClient_ExceptionEvent; var dataKeyRequest = new GenerateDataKeyRequest() { KeyId = cmk, //"alias/console-test1846939174-user1846939660" KeySpec = DataKeySpec.AES_128 }; GenerateDataKeyResponse dataKeyResponse = kmsClient.GenerateDataKey(dataKeyRequest); var plaintextKey = await StreamToByteArray(dataKeyResponse.Plaintext); var encryptedKey = await StreamToByteArray(dataKeyResponse.CiphertextBlob); var key = encryptedKey; var encryptedResponse = await kmsClient.EncryptAsync(new EncryptRequest() { KeyId = cmk, Plaintext = jsonMemStream, }, token); var dataBytes = await GetByteDataPackage(encryptedResponse, key); //var dataBytes = Encoding.ASCII.GetBytes(dataPack); return(dataBytes); } catch (Exception exc) //took just over 15 seconds { } return(null); }
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)); }
public async Task EnvelopeAsync(byte[] unencryptedBytes, int symmetricKeySizeBits, int symmetricInitializationVectorSizeBits, Stream encryptedOutputStream, CancellationToken cancellationToken) { try { AmazonS3Credentials kmsCredentials = await GetCredentialsAsync(); if (symmetricKeySizeBits != 256) { throw new ArgumentOutOfRangeException(nameof(symmetricKeySizeBits), "Invalid value " + symmetricKeySizeBits + ". Only 256-bit keys are supported."); } if (symmetricInitializationVectorSizeBits != 128) { throw new ArgumentOutOfRangeException(nameof(symmetricInitializationVectorSizeBits), "Invalid value " + symmetricInitializationVectorSizeBits + ". Only 128-bit initialization vectors are supported."); } AmazonKeyManagementServiceClient kmsClient = new AmazonKeyManagementServiceClient(kmsCredentials.AccessKeyId, kmsCredentials.SecretAccessKey, kmsCredentials.SessionToken, kmsCredentials.RegionEndpoint); // generate a symmetric data key GenerateDataKeyResponse dataKeyResponse = await kmsClient.GenerateDataKeyAsync(new GenerateDataKeyRequest { KeyId = kmsCredentials.CustomerMasterKey, KeySpec = DataKeySpec.AES_256 }, cancellationToken); // write encrypted payload // write encrypted data key length and bytes byte[] encryptedDataKeyBytes = dataKeyResponse.CiphertextBlob.ToArray(); byte[] encryptedDataKeyBytesLength = BitConverter.GetBytes(encryptedDataKeyBytes.Length); encryptedOutputStream.Write(encryptedDataKeyBytesLength, 0, encryptedDataKeyBytesLength.Length); encryptedOutputStream.Write(encryptedDataKeyBytes, 0, encryptedDataKeyBytes.Length); // write encrypted random initialization vector length and bytes Random random = new Random(); byte[] initializationVectorBytes = new byte[16]; random.NextBytes(initializationVectorBytes); byte[] encryptedInitializationVectorBytes = (await kmsClient.EncryptAsync(new EncryptRequest { KeyId = kmsCredentials.CustomerMasterKey, Plaintext = new MemoryStream(initializationVectorBytes) }, cancellationToken)).CiphertextBlob.ToArray(); byte[] encryptedInitializationVectorBytesLength = BitConverter.GetBytes(encryptedInitializationVectorBytes.Length); encryptedOutputStream.Write(encryptedInitializationVectorBytesLength, 0, encryptedInitializationVectorBytesLength.Length); encryptedOutputStream.Write(encryptedInitializationVectorBytes, 0, encryptedInitializationVectorBytes.Length); // write symmetrically encrypted bytes byte[] dataKeyBytes = dataKeyResponse.Plaintext.ToArray(); SymmetricEncryption symmetricEncryption = new SymmetricEncryption(dataKeyBytes, initializationVectorBytes); byte[] encryptedBytes = symmetricEncryption.Encrypt(unencryptedBytes); encryptedOutputStream.Write(encryptedBytes, 0, encryptedBytes.Length); } // the following catch statements attempt to filter out expected exceptions (e.g., due to naturally lacking internet connections) // from those that are fixable errors within the app. expected exceptions are logged but not reported to the app center, whereas // all others are reported to the app center. our approach is to whitelist excepted exceptions as we see them appear in the app // center, in order to ensure that we don't miss any fixable errors. catch (HttpRequestException ex) { bool logged = false; if (ex.InnerException is WebException) { WebException webException = ex.InnerException as WebException; if (IGNORED_WEB_EXCEPTION_STATUSES.Contains(webException.Status)) { LogKmsEnvelopeException(ex); logged = true; } } if (!logged) { ReportKmsEnvelopeException(ex); } throw ex; } catch (WebException webException) { if (IGNORED_WEB_EXCEPTION_STATUSES.Contains(webException.Status)) { LogKmsEnvelopeException(webException); } else { ReportKmsEnvelopeException(webException); } throw webException; } catch (OperationCanceledException ex) { LogKmsEnvelopeException(ex); throw ex; } catch (Exception ex) { ReportKmsEnvelopeException(ex); throw ex; } }