Click here to Skip to main content
15,891,204 members
Articles / Web Development / ASP.NET
Article

Automated File Decryption Using GnuPG and C#

Rate me:
Please Sign up or sign in to vote.
3.27/5 (9 votes)
11 Dec 2007CPOL2 min read 107.7K   23   20
How To: Automate decryption of PGP / GnuPG encrypted files.

Introduction

Suppose you need to decrypt and process a PGP / GnuPG encrypted file. This brief how-to will hopefully help you do that.

Background

The set up: our client needed to provide us - securely - with an XML file made available via FTP, daily. Secure FTP was not an option, and they insisted on PGP. No problem, right? Well, actually quite a few problems, which I will attempt to help you avoid here.

Obviously, you need to install PGP or its open-source pal, GnuPG. You need to create a private and public key for yourself, and provide the public key to the "encryptor". All this stuff is well documented on various sites, so I'm not going into it here. There's a nice little Windows app called "GNU Privacy Assistant" (I used version v0.5.0) that will make this job fast and easy. Google it, or get it through www.gnupg.org.

End result: a human-unreadable / GPG-encrypted document that now needs to be decrypted and processed by an automated process.

Using the code

Here's the method we use. Basically, grab your encrypted file from the file system and get a reference to it through the FileInfo class. Pass that to the method.

C#
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() just provides a name for the resulting decrypted file - it's implementation is not important. Basically, just lop the ".gpg" extension off the end of the encrypted file. The method returns the decrypted file name for further processing; again, this isn't important, and simply suited the purpose at hand.

The interesting stuff: notice we call up the Windows Command EXE using System.Diagnostics.ProcessStartInfo. The working directory is where the GnuPG application (EXE) and the public and private key files are stored.

The tricky part is passing the "secret" passphrase and options and commands to the gpg.exe process via cmd.exe. This is done through System.Diagnostics.Process.StandardInput. Essentially, you are spawning a command window and feeding it something like:

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

Problem solved! Note the security issues with having your private key passphrase used in an application like this - that's your issue! Not a big problem for our situation.

Points of interest

Notice the "-o" option? Don't use "-output", it won't work. Also notice how we build the whole command in "sCommandLine" and pass this variable to WriteLine? Also important. For some reason, building this directly in StandardInput.WriteLine() doesn't work either - probably the escape characters in C#.

Hope that helps you avoid the frustrations we went through in coming up with this solution!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer ShakingHand Software / Web / Mobile
Canada Canada
I've been making web sites and such on the .NET platform since 2001. I suppose I specialise in Microsoft technologies.

Comments and Discussions

 
QuestionThe above code is not working Pin
tinu007_in18-Feb-20 21:43
tinu007_in18-Feb-20 21:43 
SuggestionUse PgpSharp Pin
Rok Banko12-Sep-17 21:56
Rok Banko12-Sep-17 21:56 
GeneralRe: Use PgpSharp Pin
a_kiani7-Mar-18 18:44
a_kiani7-Mar-18 18:44 
GeneralThanks Pin
Kyuubi7862-Mar-17 1:58
Kyuubi7862-Mar-17 1:58 
QuestionCan't find libassuan-0.dll Pin
D Hartman28-Aug-15 4:53
D Hartman28-Aug-15 4:53 
QuestionWhere is the input path? Pin
Member 1014727529-Apr-14 5:19
Member 1014727529-Apr-14 5:19 
QuestionWhen we used above code then it ask me for passphrase Pin
vinodpatidar29-Apr-13 0:00
vinodpatidar29-Apr-13 0:00 
AnswerRe: When we used above code then it ask me for passphrase Pin
vinodpatidar2-May-13 4:46
vinodpatidar2-May-13 4:46 
Questionneed an help for encrypting file Pin
kumaran_vr11-Nov-11 5:33
kumaran_vr11-Nov-11 5:33 
QuestionProblem with binary file (.xls) to be specific Pin
Mark Ashcroft27-Jun-11 1:37
Mark Ashcroft27-Jun-11 1:37 
QuestionNothing really happens Pin
penglund12-Jan-10 2:54
penglund12-Jan-10 2:54 
AnswerRe: Nothing really happens Pin
venkatpv22-Jan-11 3:15
venkatpv22-Jan-11 3:15 
Generalnew version of GnuPG [modified] Pin
LenaBr30-Nov-09 8:49
LenaBr30-Nov-09 8:49 
Generalpassphrase passing in Pin
AWdrius12-Nov-09 0:17
AWdrius12-Nov-09 0:17 
GeneralRe: passphrase passing in Pin
Member 1155222730-Apr-15 5:41
Member 1155222730-Apr-15 5:41 
GeneralGreat, thanks! Pin
Snowbunny6-Nov-09 1:11
Snowbunny6-Nov-09 1:11 
QuestionGPG Decrypt Not Work with ASP.Net [modified] Pin
Hetal Prajapati from Ahmedabad7-Aug-09 19:53
Hetal Prajapati from Ahmedabad7-Aug-09 19:53 
AnswerRe: GPG Decrypt Not Work with ASP.Net Pin
jwooley27-Oct-09 3:57
jwooley27-Oct-09 3:57 
GeneralGreat this is perfect thank you Pin
paymeman12-Mar-09 2:15
paymeman12-Mar-09 2:15 
Answer“Notice the "-o" option? Don't use "-output", it won't work.” Pin
BugMeNot ACCOUNT7-Mar-08 3:23
BugMeNot ACCOUNT7-Mar-08 3:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.