65.9K
CodeProject 正在变化。 阅读更多。
Home

使用GnuPG和C#自动解密文件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.27/5 (9投票s)

2007 年 12 月 11 日

CPOL

2分钟阅读

viewsIcon

110180

操作方法:自动化解密 PGP / GnuPG 加密文件。

引言

假设您需要解密并处理 PGP / GnuPG 加密的文件。本简短的操作指南希望能帮助您做到这一点。

背景

具体情况:我们的客户需要以安全的方式向我们提供通过 FTP 每天提供的 XML 文件。安全 FTP 不是一个选项,他们坚持使用 PGP。这没什么问题,对吧?实际上,却存在很多问题,我将尝试在这里帮助您避免这些问题。

显然,您需要安装 PGP 或其开源伙伴 GnuPG。您需要为自己创建私钥和公钥,并将公钥提供给“加密者”。所有这些内容在各种网站上都有充分的文档记录,因此我不再赘述。有一个名为“GNU Privacy Assistant”的不错的 Windows 应用程序(我使用的是 v0.5.0 版本),可以使这项工作快速而简单。在 Google 上搜索它,或通过 www.gnupg.org 获取它。

最终结果:一个人类无法读取的 / GPG 加密文档,现在需要由自动化流程解密和处理。

使用代码

我们使用的方法如下。基本上,从文件系统中获取您的加密文件,并通过 FileInfo 类获取对其的引用。将该引用传递给该方法。

private string DecryptFile(FileInfo encryptedFile)
{
  // decrypts the file using GnuPG, saves it to the file system
  // and returns the new (decrypted) file name.

  // encrypted file: thefile.xml.gpg decrypted: thefile.xml

  string outputFileName = this.GetDecryptedFileName(encryptedFile);
  // whatever you want here - just a convention

  string path = encryptedFile.DirectoryName;
  string outputFileNameFullPath = path + "\\" + outputFileName;
  try {
      System.Diagnostics.ProcessStartInfo psi = 
        new System.Diagnostics.ProcessStartInfo("cmd.exe");
      psi.CreateNoWindow = true;
      psi.UseShellExecute = false;
      psi.RedirectStandardInput = true;
      psi.RedirectStandardOutput = true;
      psi.RedirectStandardError = true;
      psi.WorkingDirectory = "C:\\Program Files\\GnuPP\\GnuPG";

      System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi);
      // actually NEED to set this as a local string variable
      // and pass it - bombs otherwise!
      string sCommandLine = "echo " + this._passphrase + 
                            "| gpg.exe --passphrase-fd 0 -o \"" +
      outputFileNameFullPath + "\" --decrypt \"" + 
                               encryptedFile.FullName + "\"";
      process.StandardInput.WriteLine(sCommandLine);
      process.StandardInput.Flush();
      process.StandardInput.Close();
      process.WaitForExit();
      process.Close();
 }
 catch (Exception ex)
 {
  this.HandleError(ex);
 }
 return outputFileName;
}

GetDecryptedFileName() 只是为生成的解密文件提供一个名称 - 其实现并不重要。基本上,只需从加密文件的末尾删除“.gpg”扩展名即可。该方法返回解密后的文件名以供进一步处理;同样,这并不重要,只是适合手头的任务。

有趣的部分:请注意,我们使用 System.Diagnostics.ProcessStartInfo 调用 Windows 命令 EXE。工作目录是存储 GnuPG 应用程序(EXE)和公钥和私钥文件的位置。

棘手的部分是将“秘密”密码和选项和命令通过 cmd.exe 传递给 gpg.exe 进程。这通过 System.Diagnostics.Process.StandardInput 完成。本质上,您正在启动一个命令窗口并向其提供类似以下内容:

C:\> echo my passphrase goes here| gpg.exe --passphrase-fd 0 
     -o "myDecryptedOutputFileName" --decrypt "myEncryptedFileName"

问题解决了!请注意,在像这样使用私钥密码的应用程序中存在安全问题 - 这是您的问题!对于我们的情况来说,这并不是一个大问题。

关注点

请注意“-o”选项?不要使用“-output”,它将不起作用。 另外请注意,我们如何在“sCommandLine”中构建整个命令并将此变量传递给 WriteLine? 这也很重要。由于某种原因,直接在 StandardInput.WriteLine() 中构建它也不起作用 - 可能是在 C# 中的转义字符。

希望这能帮助您避免我们在想出这个解决方案时遇到的挫折!

© . All rights reserved.