/// <summary> /// Symmetrically encrypts the specified buffer using a randomly generated key. /// </summary> /// <param name="data">The data to encrypt.</param> /// <param name="encryptionVariables">Optional encryption variables to use; or <c>null</c> to use randomly generated ones.</param> /// <returns> /// The result of the encryption. /// </returns> public override SymmetricEncryptionResult Encrypt(byte[] data, SymmetricEncryptionVariables encryptionVariables) { Requires.NotNull(data, "data"); IBuffer plainTextBuffer = CryptographicBuffer.CreateFromByteArray(data); IBuffer symmetricKeyMaterial, ivBuffer; if (encryptionVariables == null) { symmetricKeyMaterial = CryptographicBuffer.GenerateRandom((uint)this.SymmetricEncryptionKeySize / 8); ivBuffer = CryptographicBuffer.GenerateRandom(SymmetricAlgorithm.BlockLength); } else { Requires.Argument(encryptionVariables.Key.Length == this.SymmetricEncryptionKeySize / 8, "key", "Incorrect length."); Requires.Argument(encryptionVariables.IV.Length == this.SymmetricEncryptionBlockSize / 8, "iv", "Incorrect length."); symmetricKeyMaterial = CryptographicBuffer.CreateFromByteArray(encryptionVariables.Key); ivBuffer = CryptographicBuffer.CreateFromByteArray(encryptionVariables.IV); } var symmetricKey = SymmetricAlgorithm.CreateSymmetricKey(symmetricKeyMaterial); var cipherTextBuffer = CryptographicEngine.Encrypt(symmetricKey, plainTextBuffer, ivBuffer); return(new SymmetricEncryptionResult( symmetricKeyMaterial.ToArray(), ivBuffer.ToArray(), cipherTextBuffer.ToArray())); }
/// <summary> /// Symmetrically encrypts a stream. /// </summary> /// <param name="plaintext">The stream of plaintext to encrypt.</param> /// <param name="ciphertext">The stream to receive the ciphertext.</param> /// <param name="encryptionVariables">An optional key and IV to use. May be <c>null</c> to use randomly generated values.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that completes when encryption has completed, whose result is the key and IV to use to decrypt the ciphertext.</returns> public override async Task <SymmetricEncryptionVariables> EncryptAsync(Stream plaintext, Stream ciphertext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken) { Requires.NotNull(plaintext, "plaintext"); Requires.NotNull(ciphertext, "ciphertext"); using (var alg = SymmetricAlgorithm.Create(this.SymmetricEncryptionConfiguration.AlgorithmName)) { alg.Mode = (CipherMode)Enum.Parse(typeof(CipherMode), this.SymmetricEncryptionConfiguration.BlockMode); alg.Padding = (PaddingMode)Enum.Parse(typeof(PaddingMode), this.SymmetricEncryptionConfiguration.Padding); alg.KeySize = this.SymmetricEncryptionKeySize; if (encryptionVariables != null) { Requires.Argument(encryptionVariables.Key.Length == this.SymmetricEncryptionKeySize / 8, "key", "Incorrect length."); Requires.Argument(encryptionVariables.IV.Length == this.SymmetricEncryptionBlockSize / 8, "iv", "Incorrect length."); alg.Key = encryptionVariables.Key; alg.IV = encryptionVariables.IV; } else { encryptionVariables = new SymmetricEncryptionVariables(alg.Key, alg.IV); } using (var encryptor = alg.CreateEncryptor()) { var cryptoStream = new CryptoStream(ciphertext, encryptor, CryptoStreamMode.Write); // DON'T dispose this, or it disposes of the ciphertext stream. await plaintext.CopyToAsync(cryptoStream, alg.BlockSize, cancellationToken); cryptoStream.FlushFinalBlock(); return(encryptionVariables); } } }
public SymmetricEncryptionResult Encrypt(byte[] data, SymmetricEncryptionVariables encryptionVariables) { var rng = new Random(); byte[] key, iv; if (encryptionVariables != null) { key = encryptionVariables.Key; iv = encryptionVariables.IV; } else { key = new byte[KeyLengthInBytes]; rng.NextBytes(key); iv = new byte[KeyLengthInBytes]; rng.NextBytes(iv); } var ciphertext = new byte[key.Length + iv.Length + data.Length]; Array.Copy(key, ciphertext, key.Length); Array.Copy(iv, 0, ciphertext, key.Length, iv.Length); Array.Copy(data, 0, ciphertext, key.Length + iv.Length, data.Length); return(new SymmetricEncryptionResult(key, iv, ciphertext)); }
/// <summary> /// Symmetrically encrypts a stream. /// </summary> /// <param name="plaintext">The stream of plaintext to encrypt.</param> /// <param name="ciphertext">The stream to receive the ciphertext.</param> /// <param name="encryptionVariables">An optional key and IV to use. May be <c>null</c> to use randomly generated values.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that completes when encryption has completed, whose result is the key and IV to use to decrypt the ciphertext.</returns> public override async Task <SymmetricEncryptionVariables> EncryptAsync(Stream plaintext, Stream ciphertext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken) { var encryptor = this.GetCipher(); if (encryptionVariables == null) { var secureRandom = new SecureRandom(); byte[] key = new byte[this.SymmetricEncryptionKeySize / 8]; secureRandom.NextBytes(key); var random = new Random(); byte[] iv = new byte[encryptor.GetBlockSize()]; random.NextBytes(iv); encryptionVariables = new SymmetricEncryptionVariables(key, iv); } else { Requires.Argument(encryptionVariables.Key.Length == this.SymmetricEncryptionKeySize / 8, "key", "Incorrect length."); Requires.Argument(encryptionVariables.IV.Length == encryptor.GetBlockSize(), "iv", "Incorrect length."); } var parameters = new ParametersWithIV(new KeyParameter(encryptionVariables.Key), encryptionVariables.IV); encryptor.Init(true, parameters); await CipherStreamCopyAsync(plaintext, ciphertext, encryptor, cancellationToken); return(encryptionVariables); }
public async Task DecryptAsync(Stream ciphertext, Stream plaintext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken = default(CancellationToken)) { var buffer = new byte[ciphertext.Length - ciphertext.Position]; await ciphertext.ReadAsync(buffer, 0, buffer.Length); var oldResult = new SymmetricEncryptionResult(encryptionVariables, buffer); var plaintextBuffer = this.Decrypt(oldResult); await plaintext.WriteAsync(plaintextBuffer, 0, plaintextBuffer.Length); }
/// <summary> /// Symmetrically decrypts a stream. /// </summary> /// <param name="ciphertext">The stream of ciphertext to decrypt.</param> /// <param name="plaintext">The stream to receive the plaintext.</param> /// <param name="encryptionVariables">The key and IV to use.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> public override async Task DecryptAsync(Stream ciphertext, Stream plaintext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken) { Requires.NotNull(ciphertext, "ciphertext"); Requires.NotNull(plaintext, "plaintext"); Requires.NotNull(encryptionVariables, "encryptionVariables"); var parameters = new ParametersWithIV(new KeyParameter(encryptionVariables.Key), encryptionVariables.IV); var decryptor = this.GetCipher(); decryptor.Init(false, parameters); await CipherStreamCopyAsync(ciphertext, plaintext, decryptor, cancellationToken); }
/// <summary> /// Symmetrically decrypts a stream. /// </summary> /// <param name="ciphertext">The stream of ciphertext to decrypt.</param> /// <param name="plaintext">The stream to receive the plaintext.</param> /// <param name="encryptionVariables">The key and IV to use.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> public override async Task DecryptAsync(Stream ciphertext, Stream plaintext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken) { Requires.NotNull(ciphertext, "ciphertext"); Requires.NotNull(plaintext, "plaintext"); Requires.NotNull(encryptionVariables, "encryptionVariables"); var ciphertextMemoryStream = new MemoryStream(); await ciphertext.CopyToAsync(ciphertextMemoryStream, 4096, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); byte[] plaintextBytes = this.Decrypt(new SymmetricEncryptionResult(encryptionVariables, ciphertextMemoryStream.ToArray())); await plaintext.WriteAsync(plaintextBytes, 0, plaintextBytes.Length, cancellationToken); }
/// <summary> /// Symmetrically decrypts a stream. /// </summary> /// <param name="ciphertext">The stream of ciphertext to decrypt.</param> /// <param name="plaintext">The stream to receive the plaintext.</param> /// <param name="encryptionVariables">The key and IV to use.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that represents the asynchronous operation.</returns> public override async Task DecryptAsync(Stream ciphertext, Stream plaintext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken) { Requires.NotNull(ciphertext, "ciphertext"); Requires.NotNull(plaintext, "plaintext"); Requires.NotNull(encryptionVariables, "encryptionVariables"); using (var alg = SymmetricAlgorithm.Create(this.SymmetricEncryptionConfiguration.AlgorithmName)) { alg.Mode = (CipherMode)Enum.Parse(typeof(CipherMode), this.SymmetricEncryptionConfiguration.BlockMode); alg.Padding = (PaddingMode)Enum.Parse(typeof(PaddingMode), this.SymmetricEncryptionConfiguration.Padding); using (var decryptor = alg.CreateDecryptor(encryptionVariables.Key, encryptionVariables.IV)) { var cryptoStream = new CryptoStream(plaintext, decryptor, CryptoStreamMode.Write); // don't dispose this or it disposes the target stream. await ciphertext.CopyToAsync(cryptoStream, 4096, cancellationToken); cryptoStream.FlushFinalBlock(); } } }
/// <summary> /// Symmetrically encrypts a stream. /// </summary> /// <param name="plaintext">The stream of plaintext to encrypt.</param> /// <param name="ciphertext">The stream to receive the ciphertext.</param> /// <param name="encryptionVariables">An optional key and IV to use. May be <c>null</c> to use randomly generated values.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that completes when encryption has completed, whose result is the key and IV to use to decrypt the ciphertext.</returns> public override async Task <SymmetricEncryptionVariables> EncryptAsync(Stream plaintext, Stream ciphertext, SymmetricEncryptionVariables encryptionVariables, CancellationToken cancellationToken) { Requires.NotNull(plaintext, "plaintext"); Requires.NotNull(ciphertext, "ciphertext"); var plaintextMemoryStream = new MemoryStream(); await plaintext.CopyToAsync(plaintextMemoryStream, 4096, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); var result = this.Encrypt(plaintextMemoryStream.ToArray(), encryptionVariables); await ciphertext.WriteAsync(result.Ciphertext, 0, result.Ciphertext.Length, cancellationToken); return(result); }
public async Task <SymmetricEncryptionVariables> EncryptAsync(Stream plaintext, Stream ciphertext, SymmetricEncryptionVariables encryptionVariables = null, CancellationToken cancellationToken = default(CancellationToken)) { var plaintextBuffer = new byte[plaintext.Length - plaintext.Position]; await plaintext.ReadAsync(plaintextBuffer, 0, plaintextBuffer.Length); var result = this.Encrypt(plaintextBuffer, encryptionVariables); await ciphertext.WriteAsync(result.Ciphertext, 0, result.Ciphertext.Length); return(result); }