public static void FlushAsync() { ICryptoTransform encryptor = new IdentityTransform(1, 1, true); using (MemoryStream output = new MemoryStream()) using (CryptoStream encryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) { encryptStream.WriteAsync(new byte[] { 1, 2, 3, 4, 5 }, 0, 5); Task waitable = encryptStream.FlushAsync(new Threading.CancellationToken(false)); Assert.False(waitable.IsCanceled); encryptStream.WriteAsync(new byte[] { 1, 2, 3, 4, 5 }, 0, 5); waitable = encryptStream.FlushAsync(new Threading.CancellationToken(true)); Assert.True(waitable.IsCanceled); } }
/// <summary> /// DES 解密 /// </summary> /// <param name="val"></param> /// <returns></returns> public static async Task <string> DecryptAsync(string val) { if (string.IsNullOrEmpty(val)) { return(string.Empty); } using (var p = new DESCryptoServiceProvider()) { p.IV = Default.GetBytes(SecretKey); p.Key = Default.GetBytes(SecretKey); using (var ct = p.CreateDecryptor(p.IV, p.Key)) { var temp = Convert.FromBase64String(val); using (var ms = new MemoryStream()) { using (var cs = new CryptoStream(ms, ct, CryptoStreamMode.Write)) { await cs.WriteAsync(temp, 0, temp.Length); await cs.FlushAsync(); } return(Default.GetString(ms.ToArray())); } } } }
public async Task <byte[]> DecryptBytes(byte[] cipherText, byte[] key, byte[] iv) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) { throw new ArgumentNullException(Constants.SCipherText); } if (key == null || key.Length <= 0) { throw new ArgumentNullException(Constants.Key); } if (iv == null || iv.Length <= 0) { throw new ArgumentNullException(Constants.IV); } // Declare the RijndaelManaged object // used to decrypt the data. AesCryptoServiceProvider aesAlg = null; // Declare the string used to hold // the decrypted text. byte[] buffer; // Create a RijndaelManaged object // with the specified key and IV. using (aesAlg = new AesCryptoServiceProvider()) { //aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; aesAlg.Key = key; aesAlg.IV = iv; // Create a decrytor to perform the stream transform. using (ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV)) // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { byte[] tempbuffer = new byte[cipherText.Length]; int totalBytesRead = await csDecrypt.ReadAsync(tempbuffer, 0, tempbuffer.Length); await csDecrypt.FlushAsync(); buffer = tempbuffer.Take(totalBytesRead).ToArray(); } } // Clear the RijndaelManaged object. if (aesAlg != null) { aesAlg.Clear(); } return(buffer); }
private async Task EncryptStream(Stream input, Stream output) { var buffer = new byte[2097152]; if (string.IsNullOrEmpty(ApplicationInfo.EncryptionInfo.EncryptionKey) || string.IsNullOrEmpty(ApplicationInfo.EncryptionInfo.InitializationVector) || string.IsNullOrEmpty(ApplicationInfo.EncryptionInfo.MacKey)) { throw new IntuneWinInvalidFileException(); } var encryptionKey = Convert.FromBase64String( ApplicationInfo.EncryptionInfo.EncryptionKey); var encryptionIv = Convert.FromBase64String( ApplicationInfo.EncryptionInfo.InitializationVector); var macKey = Convert.FromBase64String( ApplicationInfo.EncryptionInfo.MacKey); await output.WriteAsync(buffer, 0, 48); using var aes = Aes.Create(); if (aes == null) { throw new InvalidOperationException(); } using var cryptoTransform = aes.CreateEncryptor(encryptionKey, encryptionIv); using var cryptoStream = new CryptoStream(output, cryptoTransform, CryptoStreamMode.Write); int count; while ((count = await input.ReadAsync(buffer, 0, buffer.Length)) > 0) { await cryptoStream.WriteAsync(buffer, 0, count); await cryptoStream.FlushAsync(); } cryptoStream.FlushFinalBlock(); output.Seek(32, SeekOrigin.Begin); await output.WriteAsync(encryptionIv, 0, encryptionIv.Length); output.Seek(32, SeekOrigin.Begin); var macHash = HmacSha256WithBufferSize(output, macKey); output.Seek(0, SeekOrigin.Begin); await output.WriteAsync(macHash, 0, macHash.Length); ApplicationInfo.EncryptionInfo.Mac = Convert.ToBase64String(macHash); await output.FlushAsync(); }
public static void Main(string[] args) { System.Console.WriteLine( typeof(object).AssemblyQualifiedName ); // http://www.drdobbs.com/windows/programming-public-key-cryptostreams-par/184416907 // X:\jsc.svn\examples\java\hybrid\JVMCLRRSACryptoServiceProviderExport\JVMCLRRSACryptoServiceProviderExport\Program.cs //var dwKeySize = (0x100 + 0x100) * 8; var dwKeySize = 128 * 8; var MaxData = (dwKeySize - 384) / 8 + 7; var RSA = new RSACryptoServiceProvider( dwKeySize: dwKeySize, parameters: new CspParameters { } ); RSAParameters p = RSA.ExportParameters(includePrivateParameters: false); var value = RSA.Encrypt( Encoding.UTF8.GetBytes("hello from server"), fOAEP: true //Encoding.UTF8.GetBytes("hello from server"), fOAEP: false ); var data = new MemoryStream(); var goo = new CryptoStream(data, new RSAEnCryptoTransform(RSA), CryptoStreamMode.Write); var text = Encoding.UTF8.GetBytes("hello".PadRight(8000) + "world"); goo.WriteAsync(text, 0, text.Length).Wait(); goo.FlushFinalBlock(); goo.FlushAsync().Wait(); var foo = new CryptoStream(data, new RSADeCryptoTransform(RSA), CryptoStreamMode.Read); //var buffer = new byte[100]; //var buffer = new byte[MaxData]; var buffer = new byte[0x1000]; var result = foo.Read(buffer, 0, buffer.Length); //var result = foo.ReadAsync(buffer, 0, buffer.Length).Result; CLRProgram.CLRMain(); }
public override async Task FlushAsync(CancellationToken ct) { if (_isDisposed) { throw new ObjectDisposedException("AESEncryptStream"); } await _cryptoStream.FlushAsync(ct).ConfigureAwait(false); await _internalStream.FlushAsync(ct).ConfigureAwait(false); }
/// <inheritdoc/> /// <exception cref="ArgumentNullException"> /// <paramref name="writeContentAsync"/> is <see langword="null"/>. /// </exception> /// <exception cref="InMemoryPersistentStorageException"> /// The item could not be created, or the item's ID could not be computed from the specified content. /// </exception> public async Task <IPersistentStorageItem> CreateOrGetItemAsync(Func <Stream, Task> writeContentAsync) { if (writeContentAsync == null) { throw new ArgumentNullException(nameof(writeContentAsync)); } PersistentStorageItemId id; using (var sha = SHA1.Create()) using (var buffer = new MemoryStream()) using (var cryptoStream = new CryptoStream(buffer, sha, CryptoStreamMode.Write)) { try { await writeContentAsync(cryptoStream); await cryptoStream.FlushAsync(); if (!cryptoStream.HasFlushedFinalBlock) { cryptoStream.FlushFinalBlock(); } } catch (Exception ex) { throw new InMemoryPersistentStorageException("Could not write item content.", ex); } try { id = new PersistentStorageItemId(sha.Hash); } catch (Exception ex) { throw new InMemoryPersistentStorageException("Could not compute identity from item content.", ex); } if (this.items.TryGetValue(id, out var item) == false) { if (buffer.TryGetBuffer(out var contentBytes) == false) { throw new InMemoryPersistentStorageException("Could not compute identity from item content."); } var content = new byte[contentBytes.Count]; Array.Copy(contentBytes.Array, contentBytes.Offset, content, 0, contentBytes.Count); item = new Item(id, content); this.items[id] = item; } return(item); } }
private async Task <byte[]> TransformAsync(byte[] buffer, ICryptoTransform transform) { using var ms = new MemoryStream(); using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write)) { await cs.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(false); await cs.FlushAsync().ConfigureAwait(false); } await ms.FlushAsync().ConfigureAwait(false); return(ms.ToArray()); }
/// <summary> /// Asynchronously decrypts data that was encrypted using <see cref="ISymmetricCryptography.EncryptWithPasswordAsync(byte[],string)"/>. /// </summary> /// <param name="encryptedBytes">The encrypted data.</param> /// <param name="password">The password that was used to encrypt the data.</param> /// <returns>The decrypted <c>byte[]</c> array.</returns> public async Task <byte[]> DecryptWithPasswordAsync(byte[] encryptedBytes, string password) { int encryptedBytesLength = encryptedBytes?.Length ?? 0; if (encryptedBytesLength <= 32 || string.IsNullOrEmpty(password)) { return(Array.Empty <byte>()); } byte[] salt = new byte[32]; for (int i = 0; i < 32; i++) { salt[i] = encryptedBytes[i]; } byte[] result; await using var output = new MemoryStream(encryptedBytesLength); await using var input = new MemoryStream(encryptedBytes, 32, encryptedBytesLength - 32); try { using var rfc = new Rfc2898DeriveBytes(password, salt, RFC_ITERATIONS); using var aes = new AesManaged { KeySize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, IV = rfc.GetBytes(16), Key = rfc.GetBytes(32) }; using ICryptoTransform decryptor = aes.CreateDecryptor(); await using var cryptoStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read); await cryptoStream.CopyToAsync(output).ConfigureAwait(false); await cryptoStream.FlushAsync().ConfigureAwait(false); result = output.ToArray(); } catch { result = null; } return(result); }
/// <summary> /// Encrypts files /// </summary> /// <param name="originalFile">file path</param> /// <param name="encFileExt">Encrypted file extension</param> public void EncryptFile(string originalFile, string encFileExt) { string EncFilename = string.Format($"{originalFile}.{encFileExt}"); using (FileStream fsRead = File.OpenRead(originalFile)) using (FileStream fsWrite = File.OpenWrite(EncFilename)) using (CryptoStream cs = new CryptoStream(fsWrite, Encryptor.CreateEncryptor(), CryptoStreamMode.Write)) { byte[] readbits = new byte[fsRead.Length]; fsRead.ReadAsync(readbits, 0, readbits.Length).Wait(); fsRead.FlushAsync().Wait(); cs.WriteAsync(readbits, 0, readbits.Length).Wait(); cs.FlushAsync().Wait(); } }
/****************************************************************************/ private async Task Transform(ICryptoTransform transform, Stream input, Stream output) { // Create an intermediate memory stream so as not to close the output stream using (var memStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write)) { await input.CopyToAsync(cryptoStream).ConfigureAwait(false); cryptoStream.FlushFinalBlock(); await cryptoStream.FlushAsync().ConfigureAwait(false); memStream.Seek(0, SeekOrigin.Begin); await memStream.CopyToAsync(output).ConfigureAwait(false); } } }
private static async Task TransformAsync(this byte[] input, ICryptoTransform transform, Stream streamToWrite, CancellationToken token, bool disposeOutput, int byteOffset, int byteCount) { using (var outputWrapper = new WrappedStream(streamToWrite, disposeOutput)) { using (var transformer = new CryptoStream(outputWrapper, transform, CryptoStreamMode.Write)) { await transformer.WriteAsync(input, byteOffset, byteCount, token).ConfigureAwait(false); await transformer.FlushAsync(token).ConfigureAwait(false); await outputWrapper.FlushAsync(token).ConfigureAwait(false); await streamToWrite.FlushAsync(token).ConfigureAwait(false); } } }
/// <summary> /// Encrypts a byte array and write to the output stream /// </summary> /// <param name="data">The data to encrypt</param> /// <param name="output">The stream to write to</param> /// <param name="statusCallback">The progress reporting callback</param> /// <returns></returns> public async Task <bool> EncryptAsync(byte[] data, Stream output) { try { var ac = new CryptoStream(output, _encryptor, CryptoStreamMode.Write); await ac.WriteAsync(data, 0, data.Length); await ac.FlushAsync(); return(true); } catch (Exception ex) { _logger?.Log(LoggingLevel.Error, ex.Message); return(false); } }
internal static async Task EncryptAsync(CryptoRequest request) { CryptoContainer container = request.ValidateEncryption(); ReportAndCancellationToken token = request.Token ?? new ReportAndCancellationToken(); token.CanReportProgress = request.InData.CanSeek; using (var aes = GetAes()) using (var encryptor = GetEncryptorAndSetAes(aes, request)) { int bufferSize = aes.BlockSize; if (token.CanReportProgress ?? false) { token.NumberOfIterations = (int)Math.Ceiling(request.InData.Length / (double)bufferSize); } CryptoStream cs = new CryptoStream(request.OutData, encryptor, CryptoStreamMode.Write); byte[] buffer = new byte[bufferSize]; int read = 0; int iterationCount = 0; while ((read = await request.InData.ReadAsync(buffer, 0, bufferSize)) > 0) { await cs.WriteAsync(buffer, 0, read); await cs.FlushAsync(); if (token.IsCanceled) { break; } iterationCount++; token.ReportProgressInternal(iterationCount); } if (token.IsCanceled) { return; } cs.FlushFinalBlock(); } if (!request.SkipValidations) { await container.WriteChecksAndEmbeddedDataAsync(); } }
/// <summary> /// Reads from <paramref name="streamToRead"/> and writes transformed data on <paramref name="streamToWrite"/>, /// using <paramref name="transform"/>, while observing <paramref name="token"/>. /// </summary> /// <param name="streamToRead">Stream to read from</param> /// <param name="transform">transform to use</param> /// <param name="streamToWrite">Stream to write transformed data to.</param> /// <param name="token">Cancellation token</param> /// <param name="disposeInput">If true, disposes <paramref name="streamToRead"/> upon operation completion, else leaves it open</param> /// <param name="disposeOutput">If true, disposes <paramref name="streamToWrite"/> upon operation completion, else leaves it open</param> /// <param name="bufferSize">Buffer size</param> public static async Task TransformAsync(this Stream streamToRead, ICryptoTransform transform, Stream streamToWrite, CancellationToken token, bool disposeInput = false, bool disposeOutput = false, int bufferSize = StdLookUps.DefaultBufferSize) { using (var outputWrapper = new WrappedStream(streamToWrite, disposeOutput)) { using (var transformer = new CryptoStream(outputWrapper, transform, CryptoStreamMode.Write)) { using (var inputWrapper = new WrappedStream(streamToRead, disposeInput)) { await inputWrapper.CopyToAsync(transformer, bufferSize, token).ConfigureAwait(false); await transformer.FlushAsync(token).ConfigureAwait(false); await outputWrapper.FlushAsync(token).ConfigureAwait(false); await streamToWrite.FlushAsync(token).ConfigureAwait(false); } } } }
private async Task DecryptStream(Stream input, Stream output) { var buffer = new byte[2097152]; if (string.IsNullOrEmpty(ApplicationInfo.EncryptionInfo.EncryptionKey) || string.IsNullOrEmpty(ApplicationInfo.EncryptionInfo.InitializationVector)) { throw new IntuneWinInvalidFileException(); } var encryptionKey = Convert.FromBase64String( ApplicationInfo.EncryptionInfo.EncryptionKey); var encryptionIv = Convert.FromBase64String( ApplicationInfo.EncryptionInfo.InitializationVector); using var aes = Aes.Create(); if (aes == null) { throw new InvalidOperationException(); } // skip HMAC signature and IV input.Seek(48, SeekOrigin.Begin); using var cryptoTransform = aes.CreateDecryptor(encryptionKey, encryptionIv); using var cryptoStream = new CryptoStream(output, cryptoTransform, CryptoStreamMode.Write); int count; while ((count = await input.ReadAsync(buffer, 0, buffer.Length)) > 0) { await cryptoStream.WriteAsync(buffer, 0, count); await cryptoStream.FlushAsync(); } cryptoStream.FlushFinalBlock(); }
private static async Task TransformChunksAsync(Stream writable, ICryptoTransform transform, int length, Encoding enc, CancellationToken token, bool disposeOutput, int chunkSize, Action <int, char[], int, int> copyToAction) { using (var outputWrapper = new WrappedStream(writable, disposeOutput)) { using (var transformer = new CryptoStream(outputWrapper, transform, CryptoStreamMode.Write)) { var bytes = enc.GetPreamble(); if (bytes.Length > 0) { await transformer.WriteAsync(bytes, 0, bytes.Length, token) .ConfigureAwait(false); } var charArr = new char[chunkSize]; bytes = new byte[enc.GetMaxByteCount(chunkSize)]; var charCnt = length; var position = 0; while (charCnt > 0) { if (charCnt > chunkSize) { charCnt = chunkSize; } copyToAction(position, charArr, 0, charCnt); var byteCnt = enc.GetBytes(charArr, 0, charCnt, bytes, 0); await transformer.WriteAsync(bytes, 0, byteCnt, token).ConfigureAwait(false); position += charCnt; charCnt = length - position; } await transformer.FlushAsync(token).ConfigureAwait(false); await outputWrapper.FlushAsync(token).ConfigureAwait(false); await writable.FlushAsync(token).ConfigureAwait(false); } } }
/// <summary> /// Asynchronously decrypts the specified <see cref="EncryptionResult"/> that was obtained using <see cref="ISymmetricCryptography.EncryptAsync(byte[])"/>. /// </summary> /// <param name="encryptionResult">The <see cref="EncryptionResult"/> that was obtained using <see cref="ISymmetricCryptography.EncryptAsync(byte[])"/>.</param> /// <returns>Decrypted <c>byte[]</c> or <c>null</c> if decryption failed.</returns> public async Task <byte[]> DecryptAsync(EncryptionResult encryptionResult) { int encryptedBytesLength = encryptionResult?.EncryptedData?.Length ?? 0; if (encryptedBytesLength == 0) { return(Array.Empty <byte>()); } byte[] result; await using var output = new MemoryStream(encryptedBytesLength); await using var input = new MemoryStream(encryptionResult.EncryptedData); try { using var aes = new AesManaged { KeySize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, IV = encryptionResult.IV, Key = encryptionResult.Key }; using ICryptoTransform decryptor = aes.CreateDecryptor(); await using var cryptoStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read); await cryptoStream.CopyToAsync(output).ConfigureAwait(false); await cryptoStream.FlushAsync(); result = output.ToArray(); } catch { result = null; } return(result); }
/****************************************************************************/ private async Task <MemoryStream> Transform(ICryptoTransform transform, byte[] data, int offset, int length) { var memory = new MemoryStream(); try { using (var cryptoStream = new CryptoStream(memory, transform, CryptoStreamMode.Write)) { await cryptoStream.WriteAsync(data, offset, length).ConfigureAwait(false); cryptoStream.FlushFinalBlock(); await cryptoStream.FlushAsync().ConfigureAwait(false); return(memory); } } catch { memory.Dispose(); throw; } }
/// <summary> /// DES加密 /// </summary> /// <param name="val"></param> /// <returns></returns> public static async Task <string> Encrypt(string val) { if (string.IsNullOrEmpty(val)) { return(string.Empty); } var d = new DESCryptoServiceProvider { IV = Encoding.UTF8.GetBytes(DesKey), Key = Encoding.UTF8.GetBytes(DesKey) }; var ct = d.CreateEncryptor(d.Key, d.IV); var temp = Encoding.UTF8.GetBytes(val); var ms = new MemoryStream(); var cs = new CryptoStream(ms, ct, CryptoStreamMode.Write); await cs.WriteAsync(temp, 0, temp.Length); await cs.FlushAsync(); cs.Close(); return(Convert.ToBase64String(ms.ToArray())); }
/// <summary> /// Decrypts files /// </summary> /// <param name="encryptedFile">encrypted file path</param> public void DecryptFile(string encryptedFile, string encFileExt) { if (!encryptedFile.EndsWith(encFileExt)) { throw new Exception("File type doesn't support"); } string enFileOldPath = encryptedFile; encryptedFile = encryptedFile.Replace(encFileExt, string.Empty); using (FileStream fsread = File.OpenRead(enFileOldPath)) using (FileStream fswrite = File.OpenWrite(encryptedFile)) using (CryptoStream cs = new CryptoStream(fswrite, Encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { byte[] bits = new byte[fsread.Length]; fsread.ReadAsync(bits, 0, bits.Length).Wait(); fsread.FlushAsync().Wait(); cs.WriteAsync(bits, 0, bits.Length).Wait(); cs.FlushAsync().Wait(); } }
public static async Task <string> Encrypt(string plainText, byte[] key, byte[] iv) { using (SymmetricAlgorithm aes = Rijndael.Create()) { aes.Key = key; aes.IV = iv; using (ICryptoTransform crypto = aes.CreateEncryptor()) { using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(ms, crypto, CryptoStreamMode.Write)) { var bytes = Encoding.UTF8.GetBytes(plainText); cryptoStream.Write(bytes, 0, bytes.Length); await cryptoStream.FlushAsync(); } var encryptedBytes = ms.ToArray(); return(Convert.ToBase64String(encryptedBytes)); } } } }
public static void Roundtrip(int inputBlockSize, int outputBlockSize, bool canTransformMultipleBlocks) { ICryptoTransform encryptor = new IdentityTransform(inputBlockSize, outputBlockSize, canTransformMultipleBlocks); ICryptoTransform decryptor = new IdentityTransform(inputBlockSize, outputBlockSize, canTransformMultipleBlocks); var stream = new MemoryStream(); using (CryptoStream encryptStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write)) { Assert.True(encryptStream.CanWrite); Assert.False(encryptStream.CanRead); Assert.False(encryptStream.CanSeek); Assert.False(encryptStream.HasFlushedFinalBlock); Assert.Throws<NotSupportedException>(() => encryptStream.SetLength(1)); Assert.Throws<NotSupportedException>(() => encryptStream.Length); Assert.Throws<NotSupportedException>(() => encryptStream.Position); Assert.Throws<NotSupportedException>(() => encryptStream.Position = 0); Assert.Throws<NotSupportedException>(() => encryptStream.Seek(0, SeekOrigin.Begin)); Assert.Throws<NotSupportedException>(() => encryptStream.Read(new byte[0], 0, 0)); Assert.Throws<NullReferenceException>(() => encryptStream.Write(null, 0, 0)); // No arg validation on buffer? Assert.Throws<ArgumentOutOfRangeException>(() => encryptStream.Write(new byte[0], -1, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => encryptStream.Write(new byte[0], 0, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => encryptStream.Write(new byte[0], 0, -1)); Assert.Throws<ArgumentException>(() => encryptStream.Write(new byte[3], 1, 4)); byte[] toWrite = Encoding.UTF8.GetBytes(LoremText); // Write it all at once encryptStream.Write(toWrite, 0, toWrite.Length); Assert.False(encryptStream.HasFlushedFinalBlock); // Write in chunks encryptStream.Write(toWrite, 0, toWrite.Length / 2); encryptStream.Write(toWrite, toWrite.Length / 2, toWrite.Length - (toWrite.Length / 2)); Assert.False(encryptStream.HasFlushedFinalBlock); // Write one byte at a time for (int i = 0; i < toWrite.Length; i++) { encryptStream.WriteByte(toWrite[i]); } Assert.False(encryptStream.HasFlushedFinalBlock); // Write async encryptStream.WriteAsync(toWrite, 0, toWrite.Length).GetAwaiter().GetResult(); Assert.False(encryptStream.HasFlushedFinalBlock); // Flush (nops) encryptStream.Flush(); encryptStream.FlushAsync().GetAwaiter().GetResult(); encryptStream.FlushFinalBlock(); Assert.Throws<NotSupportedException>(() => encryptStream.FlushFinalBlock()); Assert.True(encryptStream.HasFlushedFinalBlock); Assert.True(stream.Length > 0); } // Read/decrypt using Read stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) { Assert.False(decryptStream.CanWrite); Assert.True(decryptStream.CanRead); Assert.False(decryptStream.CanSeek); Assert.False(decryptStream.HasFlushedFinalBlock); Assert.Throws<NotSupportedException>(() => decryptStream.SetLength(1)); Assert.Throws<NotSupportedException>(() => decryptStream.Length); Assert.Throws<NotSupportedException>(() => decryptStream.Position); Assert.Throws<NotSupportedException>(() => decryptStream.Position = 0); Assert.Throws<NotSupportedException>(() => decryptStream.Seek(0, SeekOrigin.Begin)); Assert.Throws<NotSupportedException>(() => decryptStream.Write(new byte[0], 0, 0)); Assert.Throws<NullReferenceException>(() => decryptStream.Read(null, 0, 0)); // No arg validation on buffer? Assert.Throws<ArgumentOutOfRangeException>(() => decryptStream.Read(new byte[0], -1, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => decryptStream.Read(new byte[0], 0, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => decryptStream.Read(new byte[0], 0, -1)); Assert.Throws<ArgumentException>(() => decryptStream.Read(new byte[3], 1, 4)); using (StreamReader reader = new StreamReader(decryptStream)) { Assert.Equal( LoremText + LoremText + LoremText + LoremText, reader.ReadToEnd()); } } // Read/decrypt using ReadToEnd stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) using (StreamReader reader = new StreamReader(decryptStream)) { Assert.Equal( LoremText + LoremText + LoremText + LoremText, reader.ReadToEndAsync().GetAwaiter().GetResult()); } // Read/decrypt using a small buffer to force multiple calls to Read stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) using (StreamReader reader = new StreamReader(decryptStream, Encoding.UTF8, true, bufferSize: 10)) { Assert.Equal( LoremText + LoremText + LoremText + LoremText, reader.ReadToEndAsync().GetAwaiter().GetResult()); } // Read/decrypt one byte at a time with ReadByte stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) { string expectedStr = LoremText + LoremText + LoremText + LoremText; foreach (char c in expectedStr) { Assert.Equal(c, decryptStream.ReadByte()); // relies on LoremText being ASCII } Assert.Equal(-1, decryptStream.ReadByte()); } }
public static void Roundtrip(int inputBlockSize, int outputBlockSize, bool canTransformMultipleBlocks) { ICryptoTransform encryptor = new IdentityTransform(inputBlockSize, outputBlockSize, canTransformMultipleBlocks); ICryptoTransform decryptor = new IdentityTransform(inputBlockSize, outputBlockSize, canTransformMultipleBlocks); var stream = new MemoryStream(); using (CryptoStream encryptStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write)) { Assert.True(encryptStream.CanWrite); Assert.False(encryptStream.CanRead); Assert.False(encryptStream.CanSeek); Assert.False(encryptStream.HasFlushedFinalBlock); Assert.Throws <NotSupportedException>(() => encryptStream.SetLength(1)); Assert.Throws <NotSupportedException>(() => encryptStream.Length); Assert.Throws <NotSupportedException>(() => encryptStream.Position); Assert.Throws <NotSupportedException>(() => encryptStream.Position = 0); Assert.Throws <NotSupportedException>(() => encryptStream.Seek(0, SeekOrigin.Begin)); Assert.Throws <NotSupportedException>(() => encryptStream.Read(new byte[0], 0, 0)); Assert.Throws <NullReferenceException>(() => encryptStream.Write(null, 0, 0)); // No arg validation on buffer? Assert.Throws <ArgumentOutOfRangeException>(() => encryptStream.Write(new byte[0], -1, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => encryptStream.Write(new byte[0], 0, -1)); Assert.Throws <ArgumentOutOfRangeException>(() => encryptStream.Write(new byte[0], 0, -1)); Assert.Throws <ArgumentException>(() => encryptStream.Write(new byte[3], 1, 4)); byte[] toWrite = Encoding.UTF8.GetBytes(LoremText); // Write it all at once encryptStream.Write(toWrite, 0, toWrite.Length); Assert.False(encryptStream.HasFlushedFinalBlock); // Write in chunks encryptStream.Write(toWrite, 0, toWrite.Length / 2); encryptStream.Write(toWrite, toWrite.Length / 2, toWrite.Length - (toWrite.Length / 2)); Assert.False(encryptStream.HasFlushedFinalBlock); // Write one byte at a time for (int i = 0; i < toWrite.Length; i++) { encryptStream.WriteByte(toWrite[i]); } Assert.False(encryptStream.HasFlushedFinalBlock); // Write async encryptStream.WriteAsync(toWrite, 0, toWrite.Length).GetAwaiter().GetResult(); Assert.False(encryptStream.HasFlushedFinalBlock); // Flush (nops) encryptStream.Flush(); encryptStream.FlushAsync().GetAwaiter().GetResult(); encryptStream.FlushFinalBlock(); Assert.Throws <NotSupportedException>(() => encryptStream.FlushFinalBlock()); Assert.True(encryptStream.HasFlushedFinalBlock); Assert.True(stream.Length > 0); } // Read/decrypt using Read stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) { Assert.False(decryptStream.CanWrite); Assert.True(decryptStream.CanRead); Assert.False(decryptStream.CanSeek); Assert.False(decryptStream.HasFlushedFinalBlock); Assert.Throws <NotSupportedException>(() => decryptStream.SetLength(1)); Assert.Throws <NotSupportedException>(() => decryptStream.Length); Assert.Throws <NotSupportedException>(() => decryptStream.Position); Assert.Throws <NotSupportedException>(() => decryptStream.Position = 0); Assert.Throws <NotSupportedException>(() => decryptStream.Seek(0, SeekOrigin.Begin)); Assert.Throws <NotSupportedException>(() => decryptStream.Write(new byte[0], 0, 0)); Assert.Throws <NullReferenceException>(() => decryptStream.Read(null, 0, 0)); // No arg validation on buffer? Assert.Throws <ArgumentOutOfRangeException>(() => decryptStream.Read(new byte[0], -1, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => decryptStream.Read(new byte[0], 0, -1)); Assert.Throws <ArgumentOutOfRangeException>(() => decryptStream.Read(new byte[0], 0, -1)); Assert.Throws <ArgumentException>(() => decryptStream.Read(new byte[3], 1, 4)); using (StreamReader reader = new StreamReader(decryptStream)) { Assert.Equal( LoremText + LoremText + LoremText + LoremText, reader.ReadToEnd()); } } // Read/decrypt using ReadToEnd stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) using (StreamReader reader = new StreamReader(decryptStream)) { Assert.Equal( LoremText + LoremText + LoremText + LoremText, reader.ReadToEndAsync().GetAwaiter().GetResult()); } // Read/decrypt using a small buffer to force multiple calls to Read stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) using (StreamReader reader = new StreamReader(decryptStream, Encoding.UTF8, true, bufferSize: 10)) { Assert.Equal( LoremText + LoremText + LoremText + LoremText, reader.ReadToEndAsync().GetAwaiter().GetResult()); } // Read/decrypt one byte at a time with ReadByte stream = new MemoryStream(stream.ToArray()); // CryptoStream.Dispose disposes the stream using (CryptoStream decryptStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read)) { string expectedStr = LoremText + LoremText + LoremText + LoremText; foreach (char c in expectedStr) { Assert.Equal(c, decryptStream.ReadByte()); // relies on LoremText being ASCII } Assert.Equal(-1, decryptStream.ReadByte()); } }
public async Task <string> DecryptWithKey(byte[] key, EncryptedPayload encryptedData, Encoding encoding = null) { if (encoding == null) { encoding = Encoding.UTF8; } byte[] rawData = encryptedData.data.FromHex(); byte[] iv = encryptedData.iv.FromHex(); byte[] hmacReceived = encryptedData.hmac.FromHex(); using (HMACSHA256 hmac = new HMACSHA256(key)) { hmac.Initialize(); byte[] toSign = new byte[iv.Length + rawData.Length]; //copy our 2 array into one Buffer.BlockCopy(rawData, 0, toSign, 0, rawData.Length); Buffer.BlockCopy(iv, 0, toSign, rawData.Length, iv.Length); byte[] signature = hmac.ComputeHash(toSign); if (!signature.SequenceEqual(hmacReceived)) { throw new InvalidDataException("HMAC Provided does not match expected"); //Ignore } } using (AesManaged cryptor = new AesManaged()) { cryptor.Mode = CipherMode.CBC; cryptor.Padding = PaddingMode.PKCS7; cryptor.KeySize = 256; cryptor.IV = iv; cryptor.Key = key; ICryptoTransform decryptor = cryptor.CreateDecryptor(cryptor.Key, cryptor.IV); using (MemoryStream ms = new MemoryStream(rawData)) { using (MemoryStream sink = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { int read = 0; byte[] buffer = new byte[1024]; do { read = await cs.ReadAsync(buffer, 0, buffer.Length); if (read > 0) { await sink.WriteAsync(buffer, 0, read); } } while (read > 0); await cs.FlushAsync(); return(encoding.GetString(sink.ToArray())); } } } } }
public static Stream Create(Stream originalStream, string sharedSecret, string salt, bool leaveOpen) { var pipeOptions = new PipedStreamOptions() { WriteTimeout = TimeSpan.FromMinutes(10) }; var pipe = new PipedStreamManager(pipeOptions); var saltBytes = Encoding.UTF8.GetBytes(salt); var encryptorTask = Task.Run(async() => { try { using (var writerStream = pipe.CreateWriter(throwsFailedWrite: true)) using (var aesAlg = new RijndaelManaged()) using (var key = new Rfc2898DeriveBytes(sharedSecret, saltBytes)) { try { aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // prepends the IV await writerStream.WriteAsync(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int)) .IgnoreContext(); await writerStream.WriteAsync(aesAlg.IV, 0, aesAlg.IV.Length) .IgnoreContext(); // Creates an encryptor to perform the stream transform. using (var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)) using (var cryptoStream = new CryptoStream(writerStream, encryptor, CryptoStreamMode.Write)) { await originalStream.CopyToAsync(cryptoStream, bufferSize: pipeOptions.BlockSize) .IgnoreContext(); await cryptoStream.FlushAsync() .IgnoreContext(); await writerStream.FlushAsync() .IgnoreContext(); if (!cryptoStream.HasFlushedFinalBlock) { cryptoStream.FlushFinalBlock(); } await writerStream.FlushAsync() .IgnoreContext(); } } catch (Exception ex) { pipe.FaultPipe(ex); } } } finally { if (!leaveOpen) { originalStream.Dispose(); } } }); return(ReadOnlyStreamWrapper.Create(pipe.CreateReader(), onDisposingAction: (Stream s) => s?.Dispose())); }
/// <inheritdoc/> /// <exception cref="ArgumentNullException"> /// <paramref name="writeContentAsync"/> is <see langword="null"/>. /// </exception> /// <exception cref="FileSystemBasedPersistentStorageException"> /// The item could not be created, or the item's ID could not be computed from the specified content. /// </exception> public async Task <IPersistentStorageItem> CreateOrGetItemAsync(Func <Stream, Task> writeContentAsync) { if (writeContentAsync == null) { throw new ArgumentNullException(nameof(writeContentAsync)); } var temporaryFilePath = Path.GetTempFileName(); try { PersistentStorageItemId id; using (var sha = SHA1.Create()) using (var temporaryFile = File.Open(temporaryFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) using (var cryptoStream = new CryptoStream(temporaryFile, sha, CryptoStreamMode.Write)) { try { await writeContentAsync(cryptoStream); await cryptoStream.FlushAsync(); if (!cryptoStream.HasFlushedFinalBlock) { cryptoStream.FlushFinalBlock(); } } catch (Exception ex) { throw new FileSystemBasedPersistentStorageException("Could not write item content.", ex); } try { id = new PersistentStorageItemId(sha.Hash); } catch (Exception ex) { throw new FileSystemBasedPersistentStorageException("Could not compute identity from item content.", ex); } } var contentFilePath = this.GetItemContentFilePath(id); if (!File.Exists(contentFilePath)) { var contentDirectoryPath = Path.GetDirectoryName(contentFilePath); if (!Directory.Exists(contentDirectoryPath)) { try { Directory.CreateDirectory(contentDirectoryPath); } catch (Exception ex) { throw new FileSystemBasedPersistentStorageException($"Could not create subdirectory for new item `{id}`.", ex); } } try { File.Move(temporaryFilePath, contentFilePath); } catch (Exception ex) { throw new FileSystemBasedPersistentStorageException($"Could not create file for new item `{id}`.", ex); } } return(new Item(this, id)); } finally { File.Delete(temporaryFilePath); } }