使用新的加密引擎编写了一些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;
}
}