C#试图解密文件以仅处理内存



我正试图将文件解密为仅进程内存。我不希望将实际文件发送为纯文本,因为它将存储敏感数据。我根本不希望原始文本出现在系统中。

我目前正在用C:\中的一个eula文件进行测试,但无论我使用什么文件,都会遇到同样的问题。

我用AES加盐。解密文件的工作原理与现在一样,我正在将解密的数据转储到文本文档中,但当我试图将decpytedBytes编译为字符串时,它只输出文档中任何位置都不存在的3个字符。

https://i.stack.imgur.com/0531F.png

这两个字符在使用System.Text.Encoding.UTF8.GetString(bytesDecrypted, 0, bytesDecrypted.Length)将字节数组编译为字符串时显示。

我只尝试了一个基本的.ToString(),但返回了System.Byte[],只返回了

https://i.stack.imgur.com/Q3Nrc.png

当使用var str = System.Text.Encoding.Default.GetString(bytesDecrypted)时,它只输出þ*

https://i.stack.imgur.com/9H59L.png

这是我用于加密和解密的代码

public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
public void EncryptFile(string file, string fileEncrypted, string password)
{
byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
File.WriteAllBytes(fileEncrypted, bytesEncrypted);
listBox1.Items.Add("Enrypted the file");
}
public void DecryptFile(string fileEncrypted, string file, string password)
{
byte[] bytesToBeDecrypted = File.ReadAllBytes(fileEncrypted);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
listBox1.Items.Add("Attempting Decryption");
File.WriteAllBytes(file, bytesDecrypted);
var str = System.Text.Encoding.Default.GetString(bytesDecrypted);
richTextBox1.Text = str;
}

如果你对我如何做到这一点有任何想法/线索,我将不胜感激!

您使用了不正确的编码来解码解密的字节数组。原始文本文件的编码很可能是Unicode/UTF-16。因此,使用Encoding.Unicode编码将解密的字节数组解码回文本:

var str = System.Text.Encoding.Unicode.GetString(bytesDecrypted);



一些背景信息

那么,是什么让我认为原始文本文件的编码是UTF-16/Unicode?这个问题中的信息给出了一个关键提示:

使用var str=System.Text.Encoding.Default.GetString(字节解密(时,它只输出þ*

注意ÿþ。如果使用ISO/IEC 8859-1(或CP-1252(代码页解码/显示具有此BOM的文本数据,则UTF-16 LE BOM(*(就是这样显示的,该代码页通常是许多(英语/非本地化(Windows安装中使用的默认代码页。

(*(UTF-16 LE BOM(UTF-16小字节顺序标记(是两个字节0xFF、0xFE。为了了解更多关于BOM是什么以及它们的目的,我建议维基百科上的这篇文章:https://en.wikipedia.org/wiki/Byte_order_mark

找到了这个答案,我认为它适用于您的问题。特别注意"encryptedData=output.ToArray((;">

从加密流读取到流的末尾

byte[] encryptedData;
rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
rijCrypto.KeySize = 256;
using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
using (var output = new MemoryStream())
{
var encryptor = rijCrypto.CreateEncryptor();
using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
{
var buffer = new byte[1024];
var read = input.Read(buffer, 0, buffer.Length);
while (read > 0)
{
cryptStream.Write(buffer, 0, read);
read = input.Read(buffer, 0, buffer.Length);
}
cryptStream.FlushFinalBlock();
encryptedData = output.ToArray();
}
}

最新更新