使用 StreamReader 访问解密的 Rijndael 加密文件而不写入磁盘

发布于 2024-12-26 07:52:03 字数 2253 浏览 0 评论 0原文

我目前正在研究嵌入在 .dll 文件中的纯文本文件的加密/解密。纯文本文件是脚本,并且在需要时被解析。

目前,(纯文本)脚本文件的加载方式如下:

string RunLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
Assembly _assembly = Assembly.LoadFrom(RunLocation + "\\<name of dll>.dll");
s = new StreamReader(_assembly.GetManifestResourceStream(File));
RunScript(s);

RunScript 方法将脚本的单行读取为字符串,然后对其进行解析。它依次查看每一行,并在找到它们时执行我们在脚本中定义的每个操作。

由于 dll 文件无论如何都没有加密,因此我们决定在将每个脚本文件嵌入到 dll 中之前对其进行加密。我们决定使用 Rijndael 算法,因为它可以轻松地在 C#/.NET 中实现。

目前加密的运行方式如下:

FileStream fileStreamForEncryption = new FileStream (inputFileToBeEncrypted, FileMode.Create);
RijndaelManaged rijndaelCryptography = new RijndaelManaged();
CryptoStream encryptionStream = new CryptoStream(fileStreamForEncryption, rijndaelCryptography .CreateEncryptor(key, iv), CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
  cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fileStreamForEncryption .Close()

这意味着解密只需运行一些命令并获取解密的文件...除此之外,由于其余代码的设计(加密似乎是“一旦我们”如果系统按照给定的标准运行”),则文件需要作为 StreamReader 对象返回。目前,这就是我解密请求文件的方式:

string decodedFile = null;
FileStream fileToDecrypt= new FileStream(_assembly.GetManifestResourceStream(File).ToString(), FileMode.Open);
/* I know that the above line is overly complicated, it's because our files are read into StreamReader objects (as I've explained above) */
RijndaelManaged rijndaelCryptography = new RijndaelManaged();
try
{
  CryptoStream cs = new CryptoStream(fileToDecrypt, rijndaelCryptography .CreateDecryptor(key, iv), CryptoStreamMode.Read);
  using (StreamReader decryptReader = new StreamReader(cs))
  {
    decodedFile = decryptReader.ReadToEnd();
  }
catch (Exception e)
{
MessageBox.Show(e.Message);
}

有谁知道如何使用 Rijndael 解密文件,但可以将输出作为 / 读入 StreamReader 对象的实例进行访问?

我在互联网上进行了长时间的查找,寻找实现此目的的方法,最接近的方法是将解密阅读器的内容复制到另一个 StreamReader 对象中,而不是解密为字符串,但似乎您无法复制解密的内容一个 StreamReader 到另一个 StreamReader - 如果我错了,请纠正我。

我希望尽可能少地更改现有的(我没有在这里共享的)代码库,因为这可能会导致出现错误。我也希望在不将文件写回磁盘的情况下执行此操作(显然,我们对它们进行加密是有原因的)。

预先感谢您,如果我说得不够清楚或有点含糊,抱歉。如果您需要帮助我,我可以添加更多信息。

杰米

I'm currently working on encryption/decryption of plain text files that are embedded in a .dll file. The plain text files are scripts, and are being parsed as and when they're needed.

At the minute, this is how the (plain text) script files are being loaded :

string RunLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
Assembly _assembly = Assembly.LoadFrom(RunLocation + "\\<name of dll>.dll");
s = new StreamReader(_assembly.GetManifestResourceStream(File));
RunScript(s);

The RunScript method reads a single line of the script into a string, then parses it. It looks through each line in turn, and performs each of the actions we define in the script as they are found.

Since out dll files aren't encrypted in anyway, we've decided that we should encrypt each of the script files before they are embedded into the dll. We decided on the Rijndael algorithm because of the ease of which it can be implemented in C#/.NET.

Currently encryption runs like this:

FileStream fileStreamForEncryption = new FileStream (inputFileToBeEncrypted, FileMode.Create);
RijndaelManaged rijndaelCryptography = new RijndaelManaged();
CryptoStream encryptionStream = new CryptoStream(fileStreamForEncryption, rijndaelCryptography .CreateEncryptor(key, iv), CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
  cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fileStreamForEncryption .Close()

This means that decryption is a matter of running a few commands and getting the decrypted file... except that, because of the design of the rest of the code (encryption seems to have been a "once we've got the system running to a given standard"), the file needs to be returned as a StreamReader object. At the minute, this is how I'm decrypting a requested file:

string decodedFile = null;
FileStream fileToDecrypt= new FileStream(_assembly.GetManifestResourceStream(File).ToString(), FileMode.Open);
/* I know that the above line is overly complicated, it's because our files are read into StreamReader objects (as I've explained above) */
RijndaelManaged rijndaelCryptography = new RijndaelManaged();
try
{
  CryptoStream cs = new CryptoStream(fileToDecrypt, rijndaelCryptography .CreateDecryptor(key, iv), CryptoStreamMode.Read);
  using (StreamReader decryptReader = new StreamReader(cs))
  {
    decodedFile = decryptReader.ReadToEnd();
  }
catch (Exception e)
{
MessageBox.Show(e.Message);
}

Does anyone know how I can decrypt a file, using Rijndael, but have the output accessible as a / read into an instance of a StreamReader object?

I've had a long look around The Internet for ways to do this and the closest I came was copying the contents of decryptReader into another StreamReader object instead of decrypting out to a string, but it seems that you can't copy the contents of one StreamReader to another StreamReader - correct me if I'm wrong.

I'd love to have to change as little of the existing (that which I haven't shared here) code base as possible as that could cause bugs to arise. I'd also love to do this without writing the file back to disk (there's a reason we're encrypting them, obviously).

Thank you in advance, and sorry if I haven't been clear enough or a little vague. I can add more information if you need it to help me.

Jamie

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时间海 2025-01-02 07:52:03

您可以简单地将解码的文件内容转换为字节数组并将其公开为流:

var stream = new System.IO.MemoryStream(System.Text.Encoding.Unicode.GetBytes(decodedFile));
var streamReader = new StreamReader(stream);

此外,您可能应该通过将 RijndaelManaged 实例放置在 using 块中来处理它:

using (RijndaelManaged rijndaelCryptography = new RijndaelManaged())
{
    ...
}

Update< /strong>

你可以像这样获取加密文件,并且 CryptoStream 构造函数仍然会很高兴:

Stream fileToDecrypt= _assembly.GetManifestResourceStream(File);
...
CryptoStream cs = new CryptoStream(fileToDecrypt, rijndaelCryptography.CreateDecryptor(key, iv), CryptoStreamMode.Read);

You could simply convert your decoded file contents to a byte array and expose this as a stream:

var stream = new System.IO.MemoryStream(System.Text.Encoding.Unicode.GetBytes(decodedFile));
var streamReader = new StreamReader(stream);

Also, you should probably be disposing of your RijndaelManaged instance by placing it in a using block:

using (RijndaelManaged rijndaelCryptography = new RijndaelManaged())
{
    ...
}

Update

You can get the encrypted file like so, and the CryptoStream constructor will still be happy:

Stream fileToDecrypt= _assembly.GetManifestResourceStream(File);
...
CryptoStream cs = new CryptoStream(fileToDecrypt, rijndaelCryptography.CreateDecryptor(key, iv), CryptoStreamMode.Read);
暮凉 2025-01-02 07:52:03

我在互联网上进行了长时间的查找,寻找实现此目的的方法,最接近的是将decryptReader的内容复制到另一个StreamReader对象中,而不是解密为字符串,但似乎你无法复制一个 StreamReader 的内容到另一个 StreamReader - 如果我错了,请纠正我。

你只说对了一点点。虽然您无法从一个 StreamReader 复制到另一个 StreamReader,但您可以从一个 StreamReader 读取数据并写入由(例如)支持的 StreamWriter 内存流。然后,您可以将 StreamReader 包裹在 MemoryStream 中由 StreamWriter 写入的数据。

所以你想做的事情是完全有可能的。事实上,我认为您的设置最大的问题是处理解密密钥。

I've had a long look around The Internet for ways to do this and the closest I came was copying the contents of decryptReader into another StreamReader object instead of decrypting out to a string, but it seems that you can't copy the contents of one StreamReader to another StreamReader - correct me if I'm wrong.

You are only slightly correct. While you can't copy from one StreamReader to another, you can read from one StreamReader and write to a StreamWriter backed by, say, a MemoryStream. You can then wrap the StreamReader around the data in the MemoryStream that was written to by a StreamWriter.

So what you want to do is quite possible. In fact, the biggest problem I see for your setup is dealing with the decryption key.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文