Monday, June 8, 2009

PGP encrypt and sign a file with GnuPG

In order to PGP encrypt and sign a file for transfer, the following items will be needed:


  • GnuPG open source software found here


  • A private PGP Key and the corresponding public key to provide the client.


  • A clients public PGP Key.


  • A file to be encrypted.



1. Install GnuPG onto the server responsible for encrypting the file.

2. Install the keys and give proper trust level onto the server that will be encrypting the files:
gpg --import [Filename] (installs a clients public key on server)

gpg --edit [name of key] (sets trust level of client public key)
command> trust
command> 4
command> y


3. View fingerprints of keys (if needed)
gpg --fingerprint (this will show the fingerprint to the keys)


4. Execute PGP command on file gpg --passphrase-fd 0 -u %sender% -r %recipient% --yes -a --quiet --output %outfilename% --sign --encrypt %filename%

5. If the encryption will be done within an application, this key can be added to the configuration and used in a "GeneratePGPFile" function call:


6. Main Function:
protected bool GeneratePGPFile(string recipient, string filename, ref string outFilename)
{
  try
  {
    string gpgCommand = ConfigurationSettings.AppSettings["GPGCommand"];
    string gpgKeyName = ConfigurationSettings.AppSettings["GPGKeyName"];
    string gpgPassPhrase = ConfigurationSettings.AppSettings["GPGPassPhrase"]); (if needed)
    string gpgFilename = outFilename;

    gpgCommand = gpgCommand.Replace("%passphrase%", gpgPassPhrase);
    gpgCommand = gpgCommand.Replace("%sender%", string.Format("\"{0}\"", gpgKeyName));
    gpgCommand = gpgCommand.Replace("%recipient%", string.Format("\"{0}\"", recipient));
    gpgCommand = gpgCommand.Replace("%filename%", string.Format("\"{0}\"", filename));
    gpgCommand = gpgCommand.Replace("%outfilename%", string.Format("\"{0}\"", gpgFilename));

    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 = Path.GetDirectoryName(filename);

    System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi);
process.StandardInput.WriteLine(gpgCommand);

    process.StandardInput.Flush();
    process.StandardInput.Close();
    process.WaitForExit();
    process.Close();

    if (!File.Exists(gpgFilename)) {
      return false;
    }

  return true;
  }
  catch (Exception ex)
  {
    HandleError(ex);
    return false;
  }
}