Beispiel #1
0
        public static async Task <bool> Decrypt(Stream inputStream, Stream outputStream, string userId, string password)
        {
            try
            {
                var sha256 = SHA256.Create();
                using (var aes = new RijndaelManaged())
                {
                    aes.Key = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
                    aes.IV  = GetIvFrom(userId);

                    using (var decryptor = aes.CreateDecryptor())
                    {
                        using (CryptoStream csEncrypt = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
                        {
                            var buffer = new byte[2048];
                            var length = await csEncrypt.ReadAsync(buffer, 0, buffer.Length);

                            do
                            {
                                await outputStream.WriteAsync(buffer, 0, length);

                                length = await csEncrypt.ReadAsync(buffer, 0, buffer.Length);
                            } while (length > 0);
                        }
                    }
                }
                return(true);
            }
            catch (CryptographicException e)
            {
                throw e;
            }
        }
        public async Task DecryptStreamAsync(Key key, Stream sourceStream, long sourceLength, Stream destinationStream, IProgress <KryptoProgress> progress = null, CancellationToken cancellationToken = default)
        {
            DateTime started   = DateTime.Now;
            long     totalRead = 0;

            using var alg = CreateAlg(key);
            alg.IV        = await ReadBytesAsync(sourceStream, IVSize, cancellationToken).ConfigureAwait(false);

            if (progress != null)
            {
                sourceLength += alg.IV.Length;
                totalRead    += alg.IV.Length;
                progress.Report(new KryptoProgress(started, totalRead, sourceLength, false));
            }

            using var decryptor = alg.CreateDecryptor();
            using var cs        = new CryptoStream(sourceStream, decryptor, CryptoStreamMode.Read, true);

            if (progress == null)
            {
                await cs.CopyToAsync(destinationStream, Utilities.BUFFER_SIZE, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                byte[] buffer = new byte[Utilities.BUFFER_SIZE];
                int    bytesRead;
                do
                {
#if NET472
                    bytesRead = await cs.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
#else
                    bytesRead = await cs.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellationToken).ConfigureAwait(false);
#endif
                    if (bytesRead > 0)
                    {
#if NET472
                        await destinationStream.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
#else
                        await destinationStream.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
#endif
                        totalRead += bytesRead;
                        progress?.Report(new KryptoProgress(started, totalRead, sourceLength, false));
                    }
                } while (bytesRead > 0);
            }

            progress?.Report(new KryptoProgress(started, totalRead, totalRead, true));
        }
        public async Task <byte[]> Decrypt(ICryptoTransform decryptor, byte[] encrypted)
        {
            if (decryptor == null)
            {
                throw new ArgumentNullException("decryptor");
            }
            if (encrypted == null)
            {
                throw new ArgumentNullException("encrypted");
            }

            using (MemoryStream msDecrypt = new MemoryStream(encrypted))
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt,
                                                                 decryptor, CryptoStreamMode.Read))
                {
                    byte[] fromEncrypt = new byte[encrypted.Length];

                    int read = await csDecrypt.ReadAsync(fromEncrypt, 0,
                                                         fromEncrypt.Length);

                    if (read < fromEncrypt.Length)
                    {
                        byte[] clearBytes = new byte[read];
                        Buffer.BlockCopy(fromEncrypt, 0, clearBytes, 0, read);
                        return(clearBytes);
                    }
                    return(fromEncrypt);
                }
        }
        private static async Task DecryptDataStreamAsync(
            Stream data,
            byte[] secret,
            byte[] hash,
            Stream destination,
            CancellationToken cancellationToken
            )
        {
            FindDataKeyAndIv(secret, hash, out byte[] dataKey, out byte[] dataIv);

            using (var aes = Aes.Create())
            {
                // ReSharper disable once PossibleNullReferenceException
                aes.KeySize = 256;
                aes.Mode    = CipherMode.CBC;
                aes.Key     = dataKey;
                aes.IV      = dataIv;
                aes.Padding = PaddingMode.None;

                using (var decrypter = aes.CreateDecryptor())
                    using (CryptoStream aesStream = new CryptoStream(data, decrypter, CryptoStreamMode.Read))
                        using (var sha256 = SHA256.Create())
                            using (CryptoStream shaStream = new CryptoStream(aesStream, sha256, CryptoStreamMode.Read))
                            {
                                byte[] paddingBuffer = new byte[256];
                                int    read          = await shaStream.ReadAsync(paddingBuffer, 0, 256, cancellationToken)
                                                       .ConfigureAwait(false);

                                byte paddingLength = paddingBuffer[0];
                                if (paddingLength < 32)
                                {
                                    throw new PassportDataDecryptionException($"Data padding length is invalid: {paddingLength}.");
                                }

                                int actualDataLength = read - paddingLength;
                                if (actualDataLength < 1)
                                {
                                    throw new PassportDataDecryptionException($"Data length is invalid: {actualDataLength}.");
                                }

                                await destination.WriteAsync(paddingBuffer, paddingLength, actualDataLength, cancellationToken)
                                .ConfigureAwait(false);

                                // 81920 is the default Stream.CopyTo buffer size
                                // The overload without the buffer size does not accept a cancellation token
                                const int defaultBufferSize = 81920;
                                await shaStream.CopyToAsync(destination, defaultBufferSize, cancellationToken)
                                .ConfigureAwait(false);

                                byte[] paddedDataHash = sha256.Hash;
                                for (int i = 0; i < hash.Length; i++)
                                {
                                    if (hash[i] != paddedDataHash[i])
                                    {
                                        throw new PassportDataDecryptionException($"Data hash mismatch at position {i}.");
                                    }
                                }
                            }
            }
        }
Beispiel #5
0
        public static async Task <string> DecryptAsync(string data)
        {
            string decrypted;

            byte[] dataBytes = Convert.FromBase64String(data);

            using (AesManaged aes = new AesManaged())
            {
                aes.Mode         = CipherMode.CBC;
                aes.KeySize      = 256;
                aes.BlockSize    = 128;
                aes.FeedbackSize = 128;
                aes.Padding      = PaddingMode.Zeros;
                aes.Key          = System.Text.Encoding.UTF8.GetBytes(AppSettings.GetEntry("AesKey"));
                aes.IV           = System.Text.Encoding.UTF8.GetBytes(AppSettings.GetEntry("AesIV"));
                // aes.GenerateIV();

                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                using (MemoryStream ms = new MemoryStream(dataBytes))
                {
                    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] buffer = new byte[dataBytes.Length];
                        await cs.ReadAsync(buffer, 0, buffer.Length);

                        decrypted = Encoding.UTF8.GetString(buffer);
                    }
                }
            }

            return(decrypted);
        }
Beispiel #6
0
        public async Task <byte[]> DecryptAsync(byte[] data, string password)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException(nameof(password));
            }

            using (var deriveBytes = new Rfc2898DeriveBytes(password, _salt))
                using (var symmetricKey = new RijndaelManaged {
                    Mode = CipherMode.CBC, Padding = PaddingMode.None
                })
                    using (var decryptor = symmetricKey.CreateDecryptor(deriveBytes.GetBytes(256 / 8), _rgbIV))
                        using (var memoryStream = new MemoryStream(data))
                            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                            {
                                var decrypted          = new byte[data.Length];
                                var decryptedByteCount = await cryptoStream.ReadAsync(decrypted, 0, decrypted.Length);

                                return(decrypted.TakeWhile(c => c != '\0').ToArray());
                            }
        }
        public async Task DecryptAsync(Stream source, Stream dest, byte[] key)
        {
            source.Seek(0, SeekOrigin.End);
            int size = (int)source.Position;

            source.Seek(0, SeekOrigin.Begin);

            _cryptoProvider.Key = key;

            var ivBuffer = new byte[IvSize];
            await source.ReadAsync(ivBuffer, 0, IvSize);

            _cryptoProvider.IV = ivBuffer;

            var keyHash = new byte[HashSize];
            await source.ReadAsync(keyHash, 0, HashSize);

            if (!Enumerable.SequenceEqual(_hashProvider.ComputeHash(key), keyHash))
            {
                throw new InvalidKeyException();
            }

            using (var cs = new CryptoStream(source, _cryptoProvider.CreateDecryptor(), CryptoStreamMode.Read))
            {
                var buffer = new byte[size];
                await cs.ReadAsync(buffer, 0, size);

                await dest.WriteAsync(buffer, 0, size);
            }
        }
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken ct)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException("AESDecryptStream");
            }

            if (_cryptoStream == null)
            {
                var ivLengthBytes = new byte[4];
                var read          = await _internalStream.ReadAsync(ivLengthBytes, 0, 4, ct).ConfigureAwait(false);

                if (read != 4)
                {
                    throw new InvalidOperationException("Stream did not have enough data for IV length");
                }

                var ivLength = BitConverter.ToInt32(ivLengthBytes, 0);
                var iv       = new byte[ivLength];
                read = await _internalStream.ReadAsync(iv, 0, ivLength, ct).ConfigureAwait(false);

                if (read != ivLength)
                {
                    throw new InvalidOperationException("Stream did not have enough data for IV");
                }

                var aesProvider = new RijndaelManaged();
                aesProvider.Key = _aesKey;
                aesProvider.IV  = iv;
                var decryptor = aesProvider.CreateDecryptor();
                _cryptoStream = new CryptoStream(_internalStream, decryptor, CryptoStreamMode.Read);
            }

            return(await _cryptoStream.ReadAsync(buffer, offset, count, ct).ConfigureAwait(false));
        }
Beispiel #9
0
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken ct)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException("AESEncryptStream");
            }

            int read = 0;

            if (_initialBytes != null)
            {
                var max    = _initialBytes.Length - _initialBytesWritten;
                var length = Math.Min(count, max);
                Buffer.BlockCopy(_initialBytes, _initialBytesWritten, buffer, offset, length);

                read   += length;
                offset += length;
                count  -= length;
                _initialBytesWritten += length;

                if (_initialBytesWritten >= _initialBytes.Length)
                {
                    _initialBytes = null;
                }
            }

            if (count > 0)
            {
                read += await _cryptoStream.ReadAsync(buffer, offset, count, ct).ConfigureAwait(false);
            }

            return(read);
        }
        public async Task <T> DeserializeAsync <T>(Stream source, byte[] key)
        {
            _cryptoProvider.Key = key;

            var ivBuffer = new byte[IvSize];
            await source.ReadAsync(ivBuffer, 0, IvSize);

            _cryptoProvider.IV = ivBuffer;

            var keyHash = new byte[HashSize];
            await source.ReadAsync(keyHash, 0, HashSize);

            if (!Enumerable.SequenceEqual(_hashProvider.ComputeHash(key), keyHash))
            {
                throw new InvalidKeyException();
            }

            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(source, _cryptoProvider.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    var buffer    = new byte[BufferSize];
                    int bytesRead = 0;
                    while ((bytesRead = await cs.ReadAsync(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, bytesRead);
                    }
                    ms.Seek(0, SeekOrigin.Begin);

                    return((T) new BinaryFormatter().Deserialize(ms));
                }
            }
        }
Beispiel #11
0
        public async static Task <string> DecryptAsync(string cipherText, string passPhrase)
        {
            var cipherTextBytes = Convert.FromBase64String(cipherText);

            using (var password = new Rfc2898DeriveBytes(passPhrase, InitVectorBytes))
            {
                var keyBytes = password.GetBytes(Keysize / 8);
                using (var symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode    = CipherMode.CBC;
                    symmetricKey.Padding = PaddingMode.PKCS7;
                    using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, InitVectorBytes))
                    {
                        using (var memoryStream = new MemoryStream(cipherTextBytes))
                        {
                            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                            {
                                var plainTextBytes     = new byte[cipherTextBytes.Length];
                                var decryptedByteCount = await cryptoStream.ReadAsync(plainTextBytes, 0, plainTextBytes.Length);

                                return(Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount));
                            }
                        }
                    }
                }
            }
        }
Beispiel #12
0
 public async Task <byte[]> DecryptBytes(byte[] bytes)
 {
     try
     {
         PartialDecryptionBuffer = PartialDecryptionBuffer.Concat(bytes).ToArray();
         var iv = PartialDecryptionBuffer.Take(16).ToArray();
         using (var aes = Aes.Create())
         {
             aes.Key = Key;
             aes.IV  = iv;
             int    bytesRead;
             byte[] buffer;
             using (var decryptor = aes.CreateDecryptor(Key, iv))
             {
                 using (var ms = new MemoryStream(PartialDecryptionBuffer.Skip(16).ToArray()))
                 {
                     using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                     {
                         buffer    = new byte[PartialDecryptionBuffer.Skip(16).Count()];
                         bytesRead = await cs.ReadAsync(buffer, 0, buffer.Length);
                     }
                     PartialDecryptionBuffer = new byte[0];
                     return(buffer.Take(bytesRead).ToArray());
                 }
             }
         }
     }
     catch
     {
         return(null);
     }
 }
        /// <summary>
        /// Decrypts a <paramref name="cipher"/>.
        /// </summary>
        /// <param name="cipher">The cipher.</param>
        /// <param name="key">The encryption secret.</param>
        /// <param name="iv">The encryption initialization vector.</param>
        /// <returns>The plain data.</returns>
        /// <exception cref="ArgumentNullException">Thrown if either
        ///		<paramref name="cipher"/>, <paramref name="key"/>,
        ///		or <paramref name="iv"/> is null.</exception>
        ///	<exception cref="ArgumentOutOfRangeException">Thrown if the length
        ///		of either <paramref name="key"/> is not 32 or of
        ///		<paramref name="iv"/> is not 16.</exception>
        public static async Task <byte[]> Decrypt(byte[] cipher, byte[] key, byte[] iv)
        {
            if (cipher == null)
            {
                throw new ArgumentNullException(nameof(cipher));
            }
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (key.Length != 32)
            {
                throw new ArgumentOutOfRangeException(nameof(key));
            }
            if (iv == null)
            {
                throw new ArgumentNullException(nameof(iv));
            }
            if (iv.Length != 16)
            {
                throw new ArgumentOutOfRangeException(nameof(iv));
            }

            byte[] data = null;
            if (cipher.Length > 0)
            {
                using (Aes aes = Aes.Create())
                {
                    aes.Key = key;
                    aes.IV  = iv;
                    ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                    using (MemoryStream memoryStream = new MemoryStream(cipher))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            using (MemoryStream outputStream = new MemoryStream())
                            {
                                int?roundLength = null;
                                var roundBuffer = new byte[1024];
                                while ((roundLength == null) || (roundLength == roundBuffer.Length))
                                {
                                    roundLength = await cryptoStream.ReadAsync(roundBuffer, 0, roundBuffer.Length);

                                    if (roundLength > 0)
                                    {
                                        await outputStream.WriteAsync(roundBuffer, 0, roundLength.Value);
                                    }
                                }

                                data = outputStream.ToArray();
                            }
                        }
                    }
                }
            }

            return(data);
        }
        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);
        }
Beispiel #15
0
        public static async Task AES_Decrypt(string inputFile, byte[] passwordBytes)
        {
            if (!inputFile.ToLower().EndsWith(Extension))
            {
                return;
            }
            //todo:
            // - create error message on wrong password
            // - on cancel: close and delete file
            // - on wrong password: close and delete file!
            // - create a better filen name
            // - could be check md5 hash on the files but it make this slow

            var buffer = new byte[BufferSize];

            try
            {
                using (var fsCrypt = File.OpenRead(inputFile))
                {
                    var salt = new byte[SaltLength];
                    fsCrypt.Read(salt, 0, salt.Length);

                    var AES = new RijndaelManaged
                    {
                        KeySize   = KeySize,
                        BlockSize = BlockSize,
                        Padding   = PaddingMode.PKCS7,
                        Mode      = CipherMode.CFB
                    };
                    var key = new Rfc2898DeriveBytes(passwordBytes, salt, IterationCount);
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV  = key.GetBytes(AES.BlockSize / 8);

                    using (var cs = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        inputFile = inputFile.Substring(0, inputFile.Length - Extension.Length);
                        using (var fsOut = new FileStream(inputFile, FileMode.Create))
                        {
                            int read;
                            while ((read = await cs.ReadAsync(buffer, 0, buffer.Length)) > 0)
                            {
                                fsOut.Write(buffer, 0, read);
                            }
                        }
                    }
                }
            }
            catch (CryptographicException exCryptographicException)
            {
                Debug.WriteLine("CryptographicException error: " + exCryptographicException.Message);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error: " + ex.Message);
            }
        }
 public void GenerateRandom()
 {
     byte[] rng = new byte[Program.RNG_COUNT * Program.INT_SIZE];
     using (SymmetricAlgorithm salsa20 = new Salsa20())
         using (ICryptoTransform encrypt = salsa20.CreateEncryptor(Guid.NewGuid().ToByteArray(),
                                                                   Guid.NewGuid().ToByteArray().Take(8).ToArray()))
             using (MemoryStream streamInput = new MemoryStream(rng, false))
                 using (CryptoStream streamEncrypted = new CryptoStream(streamInput, encrypt, CryptoStreamMode.Read))
                 {
                     streamEncrypted.ReadAsync(rng).GetAwaiter().GetResult();
                 }
 }
Beispiel #17
0
        private static async Task DecryptAsync(string InputPath)
        {
            // Get password from user.
            // TODO: Hide and confirm password.
            ThreadsafeConsole.Write("Enter password: "******"Output filename is {outputFilename}.");
                // Generate key from password (provided by user) and salt (stored in encrypted file).
                using (var keyDerivation = KeyDerivation.Create(encryptedFileHeader.KeyDerivationAlgorithm, password, encryptedFileHeader.Salt, encryptedFileHeader.KeyDerivationIterations))
                {
                    var key = keyDerivation.GetBytes(encryptedFileHeader.KeyLength);
                    ThreadsafeConsole.WriteLine($"Encryption key (derived from password and salt) is {Convert.ToBase64String(key)}.");
                    ThreadsafeConsole.WriteLine($"Cipher initialization vector is {Convert.ToBase64String(encryptedFileHeader.InitializationVector)}.");
                    // Create cipher from key (see above) plus algorithm name and initialization vector (stored in unencrypted header at beginning of encrypted file).
                    // Create decrypting input stream.
                    using (var cipher = Cipher.Create(encryptedFileHeader.CipherAlgorithm))
                        using (var decryptor = cipher.CreateDecryptor(key, encryptedFileHeader.InitializationVector))
                            await using (var cryptoStream = new CryptoStream(inputFileStream, decryptor, CryptoStreamMode.Read))
                                await using (var outputFileStream = File.Open(outputFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None))
                                {
                                    // To limit memory usage, repeatedly read a small block from input stream and write it to the decrypted output stream.
                                    var buffer = new byte[cipher.BlockSize];
                                    int bytesRead;
                                    while ((bytesRead = await cryptoStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                    {
                                        await outputFileStream.WriteAsync(buffer, 0, bytesRead);
                                    }
                                }
                }
            }
            var encryptionDuration = _stopwatch.Elapsed - encryptionStart;

            ThreadsafeConsole.WriteLine($"Wrote decrypted file to {outputFilename}.");
            ThreadsafeConsole.WriteLine($"Decryption took {encryptionDuration.TotalSeconds.ToString(_elapsedSecondsFormat)} seconds.");
        }
Beispiel #18
0
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            if (mode != CryptoStreamMode.Read)
            {
                throw new InvalidOperationException("You cannot read from a stream in write mode.");
            }
            if (HasFlushedFinalBlock)
            {
                throw new InvalidOperationException("You cannot write on the stream when the final block was already flushed.");
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            int done = 0;

            if (first)
            {
                if (operation == CryptographicOperation.Encrypt)
                {
                    Array.Copy(iv, 0, buffer, offset, 16); // copy iv to encrypted output
                    done     += 16;                        // the method returns the iv so it has to be counted
                    offset   += 16;
                    count    -= 16;
                    transform = csp.CreateEncryptor(key, iv);
                    shaStream = new CryptoStream(stream, sha, CryptoStreamMode.Read);          // compute SHA256 of plain data
                    aesStream = new CryptoStream(shaStream, transform, CryptoStreamMode.Read); // encrypt after computing hash
                    topStream = aesStream;                                                     // Following operations will be done on this stream.
                    first     = false;
                }
                else // CryptographicOperation.Decrypt
                {
                    iv = new byte[16];
                    if (await stream.ReadAsync(iv, 0, 16).ConfigureAwait(false) < 16)
                    {
                        return(-1);                                                              // read iv from stream
                    }
                    // The method does not return an iv and its length is ignored.
                    transform = csp.CreateDecryptor(key, iv);
                    aesStream = new CryptoStream(stream, transform, CryptoStreamMode.Read); // first decrypt data
                    shaStream = new CryptoStream(aesStream, sha, CryptoStreamMode.Read);    // then compute hash of the plain data
                    topStream = shaStream;                                                  // Following operations will be done on this stream.
                    first     = false;
                }
            }
            done += await topStream.ReadAsync(buffer, offset, count).ConfigureAwait(false);

            _position += done;
            return(done);
        }
Beispiel #19
0
        public async Task <byte[]> Decrypt(byte[] input)
        {
            var decryptor = CreateDecryptor();

            var inputBytes = Convert.FromBase64String(Convert.ToBase64String(input));

            byte[] plainTextBytes = new byte[inputBytes.Length];

            using MemoryStream memoryStream = new MemoryStream(inputBytes);

            using CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);

            await cryptoStream.ReadAsync(plainTextBytes, 0, plainTextBytes.Length);

            return(plainTextBytes);
        }
Beispiel #20
0
        public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
        {
            if (mode != CryptoStreamMode.Read)
            {
                throw new InvalidOperationException("You cannot read from a stream in write mode.");
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            int done = await shaStream.ReadAsync(buffer, offset, count).ConfigureAwait(false);

            _position += done;
            return(done);
        }
Beispiel #21
0
        public async Task <byte[]> DecryptAsync(Stream cypherStream)
        {
            using TripleDES des = TripleDES.Create();
            var pdb = new Rfc2898DeriveBytes(encryptionKey.ToInsecureString(),
                                             salt);

            des.Key      = pdb.GetBytes(keySize);
            des.IV       = pdb.GetBytes(ivSize);
            using var cs = new CryptoStream(cypherStream,
                                            des.CreateDecryptor(),
                                            CryptoStreamMode.Read);
            byte[] fromEncrypt = new byte[cypherStream.Length];
            await cs.ReadAsync(fromEncrypt.AsMemory(0, fromEncrypt.Length));

            cs.Close();
            return(TrimNullByte(fromEncrypt));
        }
        public async Task <string> DecryptStringAsync(string encryptedData, byte[] key, byte[] iv, CancellationToken cancellationToken = default(CancellationToken))
        {
            var cipherTextBytes = Convert.FromBase64String(encryptedData);
            var plainTextBytes  = new byte[cipherTextBytes.Length];

            using (var rijndael = System.Security.Cryptography.Rijndael.Create())
                using (var memoryStream = new MemoryStream(cipherTextBytes))
                    using (var cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(key, iv), CryptoStreamMode.Read))
                    {
                        var decryptedByteCount = await cryptoStream.ReadAsync(plainTextBytes, 0, plainTextBytes.Length, cancellationToken).ConfigureAwait(false);

                        memoryStream.Close();
                        cryptoStream.Close();
                        rijndael.Clear();
                        return(Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount));
                    }
        }
Beispiel #23
0
        public async Task <string> Decrypt(string encryptedText, AppSettings appsettings)
        {
            byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
            byte[] keyBytes        = new Rfc2898DeriveBytes(appsettings.SecretSystemHashKey, Encoding.ASCII.GetBytes(appsettings.SystemSaltKey)).GetBytes(256 / 8);
            byte[] plainTextBytes  = new byte[cipherTextBytes.Length];
            int    decryptedByteCount;

            using (var symmetricKey = new RijndaelManaged()
            {
                Mode = CipherMode.CBC, Padding = PaddingMode.None
            })
                using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(appsettings.SystemIVKey)))
                    using (var memoryStream = new MemoryStream(cipherTextBytes))
                        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            decryptedByteCount = await cryptoStream.ReadAsync(plainTextBytes, 0, plainTextBytes.Length);
                        }
            return(Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd('\0'));
        }
Beispiel #24
0
        public static async Task <MemoryStream> DecryptFileAsync(string inputFile, string password)
        {
            MemoryStream memoryStream = null;

            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

            byte[] salt = new byte[32];

            try
            {
                using (FileStream inputFileStream = new FileStream(inputFile, FileMode.Open))
                {
                    await inputFileStream.ReadAsync(salt, 0, salt.Length);

                    var AES = DefaultAESWithKey(new Rfc2898DeriveBytes(passwordBytes, salt, HashRate));

                    using (CryptoStream cryptoStream = new CryptoStream(inputFileStream, AES.CreateDecryptor(), CryptoStreamMode.Read))
                    {
                        memoryStream = new MemoryStream();

                        int read;

                        byte[] buffer = new byte[1048576];

                        while ((read = await cryptoStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                        {
                            await memoryStream.WriteAsync(buffer, 0, buffer.Length);
                        }

                        memoryStream.Position = 0;
                    }
                }
            }
            catch (Exception e)
            {
                //System.Windows.MessageBox.Show($"Method: DecryptFile() failed.\n\nMessage: { e.Message }\n\nInnerException: { e.InnerException }");

                return(null);
            }

            return(memoryStream);
        }
Beispiel #25
0
 private static async Task <byte[]> HashFileAsync(string path, HashAlgorithm hash)
 {
     using (hash) // Automatically dispose argument after usage
         using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
             using (CryptoStream cs = new CryptoStream(fs, hash, CryptoStreamMode.Read))
             {
                 byte[] buffer = new byte[8192];
                 while (true)
                 {
                     if (await cs.ReadAsync(buffer, 0, buffer.Length) < buffer.Length)
                     {
                         if (!cs.HasFlushedFinalBlock)
                         {
                             cs.FlushFinalBlock();
                         }
                         return(hash.Hash);
                     }
                 }
             }
 }
Beispiel #26
0
        /// <summary>
        /// Computes the hash value for the specified <see cref="Stream"/> object asynchronously.
        /// </summary>
        /// <param name="hashAlgorithm">The cryptographic hash algorithm.</param>
        /// <param name="stream">The input to compute the hash code for.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A task that represents the asynchronous compute operation. The value of the task's <see cref="Task{TResult}.Result"/> parameter contains the computed hash code.</returns>
        public async Task <byte[]> ComputeHashAsync(HashAlgorithm hashAlgorithm, Stream stream, CancellationToken cancellationToken)
        {
            Argument.NotNull(hashAlgorithm, nameof(hashAlgorithm));
            Argument.NotNull(stream, nameof(stream));

            using (var decoratedStream = new ControlDisposalStreamDecorator(stream, leaveOpen: true))
                using (var cryptoStream = new CryptoStream(decoratedStream, hashAlgorithm, CryptoStreamMode.Read))
                {
                    byte[] buffer = new byte[BufferSize];

                    int read;

                    while ((read = await cryptoStream
                                   .ReadAsync(buffer, 0, buffer.Length, cancellationToken)
                                   .ConfigureAwait(Await.Default)) > 0)
                    {
                    }

                    return(hashAlgorithm.Hash);
                }
        }
        public async static Task <string> Decrypt(string cipherText, string passPhrase)
        {
            // Get the complete stream of bytes that represent:
            // [32 bytes of Salt] + [16 bytes of IV] + [n bytes of CipherText]
            var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
            // Get the saltbytes by extracting the first 16 bytes from the supplied cipherText bytes.
            var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
            // Get the IV bytes by extracting the next 16 bytes from the supplied cipherText bytes.
            var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
            // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
            var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();

            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
            {
                var keyBytes = password.GetBytes(Keysize / 8);
                using (var symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.BlockSize = 128;
                    symmetricKey.Mode      = CipherMode.CBC;
                    symmetricKey.Padding   = PaddingMode.PKCS7;
                    using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
                    {
                        using (var memoryStream = new MemoryStream(cipherTextBytes))
                        {
                            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                            {
                                var plainTextBytes     = new byte[cipherTextBytes.Length];
                                var decryptedByteCount = await cryptoStream.ReadAsync(plainTextBytes, 0, plainTextBytes.Length);

                                memoryStream.Close();
                                cryptoStream.Close();
                                return(Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount));
                            }
                        }
                    }
                }
            }
        }
        public static async Task <byte[]> DecryptAsync(byte[] value, IEncryptionCredentials credentials,
                                                       CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (value == null || value.Length == 0)
            {
                return(value);
            }

            byte[] passwordBytes      = null;
            byte[] saltBytes          = null;
            byte[] initialVectorBytes = null;
            byte[] derivedBytes       = null;
            byte[] valueBytes         = null;
            byte[] buffer             = null;

            try
            {
                passwordBytes      = credentials.Password.ToByteArray(Encoding.ASCII, clearAfterUse: true);
                saltBytes          = credentials.Salt.ToByteArray(Encoding.ASCII, clearAfterUse: true);
                initialVectorBytes = credentials.InitialVector.ToByteArray(Encoding.ASCII, clearAfterUse: true);
                var passwordIterations = credentials.PasswordIterations;
                var keySize            = credentials.KeySize;
                valueBytes = Convert.FromBase64String(Encoding.ASCII.GetString(value));
                buffer     = new byte[valueBytes.Length];
                using var rfcDeriveBytes     = new Rfc2898DeriveBytes(passwordBytes, saltBytes, passwordIterations);
                using var aesManaged         = new AesManaged { Mode = CipherMode.CBC };
                derivedBytes                 = rfcDeriveBytes.GetBytes(keySize / 8);
                using var decryptor          = aesManaged.CreateDecryptor(derivedBytes, initialVectorBytes);
                await using var memoryStream = new MemoryStream(valueBytes);
                await using var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
                var count = await cryptoStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

                memoryStream.Close();
                cryptoStream.Close();
                aesManaged.Clear();
                Array.Resize(ref buffer, count);
                return(buffer);
            }
            finally
            {
                if (buffer != null && buffer.Any())
                {
                    Array.Clear(buffer, 0, buffer.Length);
                }
                if (passwordBytes != null && passwordBytes.Any())
                {
                    Array.Clear(passwordBytes, 0, passwordBytes.Length);
                }
                if (valueBytes != null && valueBytes.Any())
                {
                    Array.Clear(valueBytes, 0, valueBytes.Length);
                }
                if (saltBytes != null && saltBytes.Any())
                {
                    Array.Clear(saltBytes, 0, saltBytes.Length);
                }
                if (initialVectorBytes != null && initialVectorBytes.Any())
                {
                    Array.Clear(initialVectorBytes, 0, initialVectorBytes.Length);
                }
                if (derivedBytes != null && derivedBytes.Any())
                {
                    Array.Clear(derivedBytes, 0, derivedBytes.Length);
                }
            }
        }
Beispiel #29
0
        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()));
                        }
                    }
                }
            }
        }
Beispiel #30
0
        public static async Task <bool> AppendStringToFile(string fileName, string plainText, byte[] key, byte[] iv)
        {
            try
            {
                using (Rijndael algo = Rijndael.Create())
                {
                    algo.Key = key;
                    // The IV is set below
                    algo.Mode    = CipherMode.CBC;
                    algo.Padding = PaddingMode.PKCS7;

                    // Create the streams used for encryption.
                    using (FileStream file = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        byte[] previous       = null;
                        int    previousLength = 0;

                        long length = file.Length;

                        // No check is done that the file is correct!
                        if (length != 0)
                        {
                            // The IV length is equal to the block length
                            byte[] block = new byte[iv.Length];

                            if (length >= iv.Length * 2)
                            {
                                // At least 2 blocks, take the penultimate block
                                // as the IV
                                file.Position = length - iv.Length * 2;
                                file.Read(block, 0, block.Length);
                                algo.IV = block;
                            }
                            else
                            {
                                // A single block present, use the IV given
                                file.Position = length - iv.Length;
                                algo.IV       = iv;
                            }

                            // Read the last block
                            file.Read(block, 0, block.Length);

                            // And reposition at the beginning of the last block
                            file.Position = length - iv.Length;

                            // We use a MemoryStream because the CryptoStream
                            // will close the Stream at the end
                            using (var ms = new MemoryStream(block))
                                // Create a decrytor to perform the stream transform.
                                using (ICryptoTransform decryptor = algo.CreateDecryptor())
                                    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                                    {
                                        // Read all data from the stream. The decrypted last
                                        // block can be long up to block length characters
                                        // (so up to iv.Length) (this with AES + CBC)
                                        previous       = new byte[iv.Length];
                                        previousLength = await cs.ReadAsync(previous, 0, previous.Length);
                                    }
                        }
                        else
                        {
                            // Use the IV given
                            algo.IV = iv;
                        }

                        // Create an encryptor to perform the stream transform.
                        using (ICryptoTransform encryptor = algo.CreateEncryptor())
                            using (CryptoStream cs = new CryptoStream(file, encryptor, CryptoStreamMode.Write))
                                using (StreamWriter sw = new StreamWriter(cs))
                                {
                                    // Rewrite the last block, if present. We even skip
                                    // the case of block present but empty
                                    if (previousLength != 0)
                                    {
                                        await cs.WriteAsync(previous, 0, previousLength);
                                    }

                                    // Write all data to the stream.
                                    await sw.WriteAsync(plainText);
                                }
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }