加密和解密代码的C#UWP文件输出似乎停止工作超过128 MB的文件

时间:2018-02-07 03:28:00

标签: c# encryption uwp

使用新的加密引擎编写了一些C#UWP代码来加密文件,并且最近添加了代码,通过将文件分成多个部分并单独加密每个部分,因为它可以处理更大的文件,因为库加密和解密函数不会采取巨大的缓冲。现在,似乎在某些情况下要么不向文件输出任何内容,要么给出" system.exception" Visual Studio调试器中的错误,您可以想象,它不是非常有用。这是该计划的这部分代码:

private async System.Threading.Tasks.Task encryptFile(StorageFile file, string key)
        {
            Loading.IsActive = true;
            string HashAlgorithmName = HashAlgorithmNames.Md5;
            HashAlgorithmProvider HashProvider = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmName);
            CryptographicHash HashObject = HashProvider.CreateHash();
            Windows.Storage.Streams.IBuffer keyAsBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf16BE);
            HashObject.Append(keyAsBuffer);
            Windows.Storage.Streams.IBuffer hashedKeyAsBuffer = HashObject.GetValueAndReset();
            string hashedKey = CryptographicBuffer.EncodeToBase64String(hashedKeyAsBuffer);
            key = hashedKey;
            string algorithmName = SymmetricAlgorithmNames.AesEcbPkcs7;
            SymmetricKeyAlgorithmProvider encryptionProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
            Windows.Storage.Streams.IBuffer keyBuffer = CryptographicBuffer.CreateFromByteArray(Encoding.ASCII.GetBytes(key));
            CryptographicKey fullKey = encryptionProvider.CreateSymmetricKey(keyBuffer);
            Stream fileStream = await file.OpenStreamForReadAsync();
            byte[] fileBytes = ReadToEnd(fileStream);
            Stream writeFileStream = await file.OpenStreamForWriteAsync();
            IEnumerable<byte[]> splitFileBytes = ArraySplit(fileBytes, 100000000);
            writeFileStream.Seek(0, SeekOrigin.Begin);
            foreach (byte[] fileBytesFor in splitFileBytes)
            {
                Windows.Storage.Streams.IBuffer fileBuffer = fileBytesFor.AsBuffer();
                Windows.Storage.Streams.IBuffer encryptedFileBuffer = CryptographicEngine.Encrypt(fullKey, fileBuffer, null);
                Stream encryptedFileStream = encryptedFileBuffer.AsStream();
                byte[] encryptedFileBytes = ReadToEnd(encryptedFileStream);
                await writeFileStream.WriteAsync(encryptedFileBytes, 0, encryptedFileBytes.Length);
                writeFileStream.Seek(0, SeekOrigin.End);
            }
            fileStream.Dispose();
            writeFileStream.Dispose();
            Loading.IsActive = false;
        }

        private async System.Threading.Tasks.Task decryptFile(StorageFile file, string key)
        {
            string HashAlgorithmName = HashAlgorithmNames.Md5;
            HashAlgorithmProvider HashProvider = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmName);
            CryptographicHash HashObject = HashProvider.CreateHash();
            Windows.Storage.Streams.IBuffer keyAsBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf16BE);
            HashObject.Append(keyAsBuffer);
            Windows.Storage.Streams.IBuffer hashedKeyAsBuffer = HashObject.GetValueAndReset();
            string hashedKey = CryptographicBuffer.EncodeToBase64String(hashedKeyAsBuffer);
            key = hashedKey;
            string algorithmName = SymmetricAlgorithmNames.AesEcbPkcs7;
            SymmetricKeyAlgorithmProvider encryptionProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
            Windows.Storage.Streams.IBuffer keyBuffer = CryptographicBuffer.CreateFromByteArray(Encoding.ASCII.GetBytes(key));
            CryptographicKey fullKey = encryptionProvider.CreateSymmetricKey(keyBuffer);
            Stream fileStream = await file.OpenStreamForReadAsync();
            byte[] fileBytes = ReadToEnd(fileStream);
            Stream writeFileStream = await file.OpenStreamForWriteAsync();
            Loading.IsActive = true;
            writeFileStream.SetLength(0);
            IEnumerable<byte[]> splitFileBytes = ArraySplit(fileBytes, 100000000);
            writeFileStream.Seek(0, SeekOrigin.Begin);
            foreach (byte[] fileBytesFor in splitFileBytes)
            {
                Windows.Storage.Streams.IBuffer fileBuffer = fileBytesFor.AsBuffer();
                Windows.Storage.Streams.IBuffer decryptedFileBuffer = CryptographicEngine.Decrypt(fullKey, fileBuffer, null);
                Stream decryptedFileStream = decryptedFileBuffer.AsStream();
                byte[] decryptedFileBytes = ReadToEnd(decryptedFileStream);
                await writeFileStream.WriteAsync(decryptedFileBytes, 0, decryptedFileBytes.Length);
                writeFileStream.Seek(0, SeekOrigin.End);
            }
            fileStream.Dispose();
            writeFileStream.Dispose();
            Loading.IsActive = false;
        }

        public static byte[] StreamToByteArray(Stream inputStream)
        {
            byte[] bytes = new byte[375000000000000000];
            using (MemoryStream memoryStream = new MemoryStream())
            {
                int count;
                while ((count = inputStream.Read(bytes, 0, bytes.Length)) > 0)
                {
                    memoryStream.Write(bytes, 0, count);
                }
                return memoryStream.ToArray();
            }
        }

        public static byte[] ReadToEnd(System.IO.Stream stream)
        {
            long originalPosition = 0;

            if (stream.CanSeek)
            {
                originalPosition = stream.Position;
                stream.Position = 0;
            }

            try
            {
                byte[] readBuffer = new byte[4096];

                int totalBytesRead = 0;
                int bytesRead;

                while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                {
                    totalBytesRead += bytesRead;

                    if (totalBytesRead == readBuffer.Length)
                    {
                        int nextByte = stream.ReadByte();
                        if (nextByte != -1)
                        {
                            byte[] temp = new byte[readBuffer.Length * 2];
                            Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                            Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                            readBuffer = temp;
                            totalBytesRead++;
                        }
                    }
                }

                byte[] buffer = readBuffer;
                if (readBuffer.Length != totalBytesRead)
                {
                    buffer = new byte[totalBytesRead];
                    Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                }
                return buffer;
            }
            finally
            {
                if (stream.CanSeek)
                {
                    stream.Position = originalPosition;
                }
            }
        }

        private IEnumerable<byte[]> ArraySplit(byte[] bArray, int intBufforLengt)
        {
            int bArrayLenght = bArray.Length;
            byte[] bReturn = null;

            int i = 0;
            for (; bArrayLenght > (i + 1) * intBufforLengt; i++)
            {
                bReturn = new byte[intBufforLengt];
                Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt);
                yield return bReturn;
            }

            int intBufforLeft = bArrayLenght - i * intBufforLengt;
            if (intBufforLeft > 0)
            {
                bReturn = new byte[intBufforLeft];
                Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft);
                yield return bReturn;
            }
        }

0 个答案:

没有答案