public override byte[] Encrypt(byte[] input, CryptoKey key) { byte[] nonce = GenerateNonce(); IAeadBlockCipher cipher = GetNewAeadBlockCipherInstance(); AeadParameters cipherParameters = GetParameters(key, nonce); try { cipher.Init(true, cipherParameters); int outputLen = cipher.GetOutputSize(input.Length); byte[] output = new byte[outputLen + nonce.Length]; int position = cipher.ProcessBytes(input, 0, input.Length, output, 0); try { cipher.DoFinal(output, position); } catch (Exception e) { throw new AppEncryptionException("unexpected error during encrypt cipher finalization", e); } AppendNonce(output, nonce); return(output); } finally { ManagedBufferUtils.WipeByteArray(cipherParameters.Key.GetKey()); } }
public override byte[] EncryptKey(CryptoKey key) { using (MetricsUtil.MetricsInstance.Measure.Timer.Time(EncryptkeyTimerOptions)) { Json kmsKeyEnvelope = new Json(); // We generate a KMS datakey (plaintext and encrypted) and encrypt its plaintext key against remaining regions. // This allows us to be able to decrypt from any of the regions locally later. GenerateDataKeyResult dataKey = GenerateDataKey(RegionToArnAndClientDictionary, out string dateKeyKeyId); byte[] dataKeyPlainText = dataKey.KeyPlaintext; try { byte[] encryptedKey = crypto.EncryptKey(key, crypto.GenerateKeyFromBytes(dataKeyPlainText)); kmsKeyEnvelope.Put(EncryptedKey, encryptedKey); ConcurrentBag <JObject> kmsRegionKeyJsonBag = new ConcurrentBag <JObject>(); Parallel.ForEach(RegionToArnAndClientDictionary.Cast <object>(), regionToArnClientObject => { DictionaryEntry regionToArnAndClient = (DictionaryEntry)regionToArnClientObject; AwsKmsArnClient arnClient = (AwsKmsArnClient)regionToArnAndClient.Value; string region = (string)regionToArnAndClient.Key; if (!arnClient.Arn.Equals(dateKeyKeyId)) { // If the ARN is different than the datakey's, call encrypt since it's another region EncryptKeyAndBuildResult( arnClient.AwsKmsClient, region, arnClient.Arn, dataKeyPlainText).IfSome(encryptedKeyResult => kmsRegionKeyJsonBag.Add(encryptedKeyResult)); } else { // This is the datakey, so build kmsKey json for it kmsRegionKeyJsonBag.Add((JObject)Option <JObject> .Some(BuildKmsRegionKeyJson( region, dateKeyKeyId, dataKey.KeyCiphertext))); } }); // TODO Consider adding minimum or quorum check on number of entries kmsKeyEnvelope.Put(KmsKeksKey, kmsRegionKeyJsonBag.ToList()); } catch (Exception e) { Logger.LogError(e, "Unexpected execution exception while encrypting KMS data key"); throw new AppEncryptionException("unexpected execution error during encrypt", e); } finally { ManagedBufferUtils.WipeByteArray(dataKeyPlainText); } return(kmsKeyEnvelope.ToUtf8()); } }
public virtual CryptoKey DecryptKey( byte[] encryptedKey, DateTimeOffset encryptedKeyCreated, CryptoKey keyEncryptionKey, bool revoked) { byte[] decryptedKey = Decrypt(encryptedKey, keyEncryptionKey); try { return(GenerateKeyFromBytes(decryptedKey, encryptedKeyCreated, revoked)); } finally { ManagedBufferUtils.WipeByteArray(decryptedKey); } }
internal virtual CryptoKey DecryptKmsEncryptedKey( IAmazonKeyManagementService awsKmsClient, byte[] cipherText, DateTimeOffset keyCreated, byte[] kmsKeyEncryptionKey, bool revoked) { byte[] plaintextBackingBytes = awsKmsClient.Decrypt(kmsKeyEncryptionKey, null); try { return(crypto.DecryptKey(cipherText, keyCreated, crypto.GenerateKeyFromBytes(plaintextBackingBytes), revoked)); } finally { ManagedBufferUtils.WipeByteArray(plaintextBackingBytes); } }
public override byte[] Decrypt(byte[] input, CryptoKey key) { byte[] nonce = GetAppendedNonce(input); IAeadBlockCipher cipher = GetNewAeadBlockCipherInstance(); AeadParameters cipherParameters = GetParameters(key, nonce); try { cipher.Init(false, cipherParameters); int cipherTextLength = input.Length - nonce.Length; int outputLen = cipher.GetOutputSize(cipherTextLength); byte[] output = new byte[outputLen]; int position = cipher.ProcessBytes(input, 0, cipherTextLength, output, 0); try { position += cipher.DoFinal(output, position); } catch (Exception e) { throw new AppEncryptionException("unexpected error during decrypt cipher finalization", e); } if (position != outputLen) { if (Debug.On) #pragma warning disable 162 { Logger.LogError("position {position} not equal to outputLength {outputLen}", position, outputLen); } #pragma warning restore 162 throw new AppEncryptionException("unexpected error during decrypt cipher finalization"); } return(output); } finally { ManagedBufferUtils.WipeByteArray(cipherParameters.Key.GetKey()); } }
/// <summary> /// Generates a random <see cref="CryptoKey"/> using the given time as the created time. /// </summary> /// /// <param name="created"> The time to associate the generated <see cref="CryptoKey"/> with.</param> /// <returns>A generated random <see cref="CryptoKey"/>.</returns> /// <exception cref="ArgumentException">Throws an exception if key length is invalid.</exception> protected internal virtual CryptoKey GenerateRandomCryptoKey(DateTimeOffset created) { int keyLengthBits = GetKeySizeBits(); if (keyLengthBits % BitsPerByte != 0) { throw new ArgumentException("Invalid key length: " + keyLengthBits); } byte[] keyBytes = new byte[keyLengthBits / BitsPerByte]; CryptoRandom.GetBytes(keyBytes); try { return(GenerateKeyFromBytes(keyBytes, created)); } finally { ManagedBufferUtils.WipeByteArray(keyBytes); } }