简体   繁体   English

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

[英]Accessing a decrypted Rijndael encrypted file with a StreamReader without writing to disk

I'm currently working on encryption/decryption of plain text files that are embedded in a .dll file. 我目前正致力于加密/解密嵌入在.dll文件中的纯文本文件。 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. RunScript方法将脚本的一行读入字符串,然后解析它。 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. 由于out dll文件无论如何都没有加密,我们决定在嵌入到dll之前加密每个脚本文件。 We decided on the Rijndael algorithm because of the ease of which it can be implemented in C#/.NET. 我们决定采用Rijndael算法,因为它可以在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. 这意味着解密是运行一些命令并获取解密文件的问题......除了因为其余代码的设计(加密似乎是“一旦我们让系统运行到一个给定的标准“),该文件需要作为StreamReader对象返回。 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? 有没有人知道如何使用Rijndael解密文件,但是可以将输出作为/ read读入StreamReader对象的实例?

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. 我已经对互联网进行了长时间的研究以了解如何做到这一点,我最接近的是将decryptReader的内容复制到另一个StreamReader对象而不是解密为字符串,但似乎你无法复制内容一个StreamReader到另一个StreamReader - 如果我错了,请纠正我。

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 杰米

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. 我已经对互联网进行了长时间的研究以了解如何做到这一点,我最接近的是将decryptReader的内容复制到另一个StreamReader对象而不是解密为字符串,但似乎你无法复制内容一个StreamReader到另一个StreamReader - 如果我错了,请纠正我。

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 . 虽然您无法从一个StreamReader复制到另一个StreamReader ,但您可以从一个StreamReader读取并写入由MemoryStream支持的StreamWriter You can then wrap the StreamReader around the data in the MemoryStream that was written to by a StreamWriter . 然后,您可以将StreamReader包装在StreamWriter写入的MemoryStream中的数据周围。

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. 事实上,我看到你设置的最大问题是处理解密密钥。

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: 此外,您可能应该通过将RijndaelManaged实例放在using块中来处置它:

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

Update 更新

You can get the encrypted file like so, and the CryptoStream constructor will still be happy: 您可以像这样获取加密文件,CryptoStream构造函数仍然会很高兴:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM