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

时间:2012-01-11 15:48:29

标签: c# .net dll embedded-resource rijndaelmanaged

我目前正致力于加密/解密嵌入在.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方法将脚本的一行读入字符串,然后解析它。它依次查看每一行,并执行我们在脚本中找到的每个动作。

由于out 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解密文件,但是可以将输出作为/ read读入StreamReader对象的实例?

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

我很乐意尽可能少地改变现有的(我在这里没有分享的)代码库,因为这可能会导致错误。我也喜欢这样做而不将文件写回磁盘(显然我们正在对它们进行加密)。

提前谢谢你,如果我不够清楚或有点含糊,请对不起。如果您需要它,我可以添加更多信息。

杰米

2 个答案:

答案 0 :(得分:2)

  

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

你只是略微正确。虽然您无法从一个StreamReader复制到另一个StreamReader,但您可以从一个StreamWriter读取并写入由MemoryStream支持的StreamReader。然后,您可以将MemoryStream包裹在由StreamWriter写入的{{1}}中的数据周围。

所以你想做的事情很有可能。事实上,我看到你设置的最大问题是处理解密密钥。

答案 1 :(得分:2)

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

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

此外,您可能应该将RijndaelManaged实例放置在使用块中来处置它:

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

<强>更新

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

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