none
Running GnuPG (GPG) from Process.Start

    Question

  • Hi all,

    Trying to run a command line containing a GPG decryption command from within C# (.Net 3.5) on Vista but getting no output.

    C# Code is...

    System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(@"cmd.exe");
    psi.CreateNoWindow = true;
    psi.UseShellExecute = false;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardInput = true;
    psi.RedirectStandardError = true;
    psi.WorkingDirectory = @"C:\Program Files\GNU\GnuPG";
    
    System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi);
    
    string cmdLine =
        @"echo mypassword | gpg.exe --passphrase-fd 0  -o  C:\gnutest\dg.txt --decrypt C:\gnutest\GPG_INPUT.ASC";
    
    process.StandardInput.WriteLine(cmdLine);
    process.StandardInput.Flush();
    process.StandardInput.Close();
    process.WaitForExit();
    process.Close();


    This runs the following DOS command which complains about an invalid password.

    "echo mypassword | gpg.exe --passphrase-fd 0  -o  C:\gnutest\dg.txt --decrypt C:\gnutest\GPG_INPUT.ASC"

    However If I remove the echo and just type the gpg.exe + args it works fine, although I am prompted for the passsword
    which would be no good from C#

    C:\gnutest>gpg.exe -o C:\gnutest\dg.txt --decrypt C:\gnutest\GPG_INPUT.ASC
    
    You need a passphrase to unlock the secret key for
    user: "David Gray (Created with GnuPg) <davidmgray_de@yahoo.co.uk>"
    1024-bit ELG-E key, ID 1E1CCBC0, created 2009-07-12 (main key ID A43DCB02)
    
    gpg: encrypted with 1024-bit ELG-E key, ID 1E1CCBC0, created 2009-07-12
          "David Gray (Created with GnuPg) <davidmgray_de@yahoo.co.uk>"
    File `C:\\gnutest\\dg.txt' exists. Overwrite? (y/N) y

    As I've typed this it's obvious that this is down to my use of GPG.EXE but I thought I would post anyone
    just in case anyone has done this before and has a solution.


    Thanks in advance
    Dave



    Sunday, July 12, 2009 1:35 PM

Answers

  • Got it working now...




    using System;
    using System.Diagnostics;
    
    namespace FileSystemExample
    {
        class FileExample
        {
    
            public static void EncryptFile(string inputName, string outputName)
            {
                const string commandFormat = @"--yes --batch --encrypt --output {0}  --armour --recipient {1} {2}";
    
                ExecuteCommandSync(string.Format(commandFormat, outputName,
                    "test@test.com",
                    inputName
                    ));
            }
    
            public static void DecryptFile(string inputName, string outputName)
            {
                const string commandFormat = @"--passphrase-fd 0 --batch --output {0} --decrypt {1}";
                ExecuteCommandSyncWithPassphrase(string.Format(commandFormat,outputName, inputName),"mypass");
            }
    
            public static void ExecuteCommandSyncWithPassphrase(string command, string password)
            {
                string path = string.Format(@"{0}\gpg.exe", @"C:\Program Files\GNU\GnuPG");
    
                var procStartInfo = new ProcessStartInfo(path, command)
                {
                    WorkingDirectory =  @"C:\Program Files\GNU\GnuPG\Work", 
                    CreateNoWindow = false,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true
                };
    
                var proc = new Process { StartInfo = procStartInfo };
                proc.Start();
                proc.StandardInput.WriteLine(password);
                proc.StandardInput.Flush();
    
                // Get the output into a string
                string result = proc.StandardOutput.ReadToEnd();
                string error = proc.StandardError.ReadToEnd();
    
                Console.WriteLine(result);
                Console.WriteLine(error);
            }
    
    
            public static void ExecuteCommandSync(string command) 
            {
                string path = string.Format(@"{0}\gpg.exe", @"C:\Program Files\GNU\GnuPG");
                Console.WriteLine(command);
                var procStartInfo = new ProcessStartInfo(path, command)
                {
                    WorkingDirectory = @"C:\Program Files\GNU\GnuPG\Work", 
                    CreateNoWindow = false,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true
                };
    
                var proc = new Process { StartInfo = procStartInfo };
                proc.Start();
    
                //proc.StandardInput.WriteLine(password);
                proc.StandardInput.Flush();
    
                // Get the output into a string
                string result = proc.StandardOutput.ReadToEnd();
                string error = proc.StandardError.ReadToEnd();
    
                Console.WriteLine(result);
                Console.WriteLine(error);
            }
    
            public static void Main()
            {
    
                EncryptFile("DAVE.TXT", "DAVE.ASC");
                DecryptFile("DAVE.ASC", "DAVE_NEW.TXT");
    
            }
        }
    }
    
    
    • Marked as answer by york0001 Monday, July 13, 2009 11:17 AM
    Monday, July 13, 2009 11:14 AM

All replies

  • I'm using GPG like this (if it's a critical application, you should decide to use securestring class for password):

    public static void EncryptFile(string inputName, string outputName)
            {
                const string commandFormat = @"--batch --output {0} --encrypt --recipient {1} {2}";
                ExecuteCommandSync(string.Format(commandFormat,
                    outputName,
                    ConfigurationManager.AppSettings[emailAddressKey],
                    inputName
                    ));
            }
    
    public static void DecryptFile(string inputName, string outputName)
            {
                const string commandFormat = @"--passphrase-fd 0 --batch --output {0} --decrypt {1}";
                ExecuteCommandSyncWithPassphrase(string.Format(commandFormat,
                    outputName, inputName));
            }
    
    public static void ExecuteCommandSyncWithPassphrase(string command, string password)
            {
                string path = string.Format(@"{0}\gpg.exe", ConfigurationManager.AppSettings[pgpPathKey]);
                var procStartInfo = new ProcessStartInfo(path, command)
                {
                    WorkingDirectory = ConfigurationManager.AppSettings[pgpPathKey],
                    CreateNoWindow = false,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true
                };
    
                var proc = new Process { StartInfo = procStartInfo };
                proc.Start();
                proc.StandardInput.WriteLine(password);
                proc.StandardInput.Flush();
    
                // Get the output into a string
                string result = proc.StandardOutput.ReadToEnd();
                string error = proc.StandardError.ReadToEnd();
    
                // Display the command output.
                TracingHelper.TraceDebug("PGP", result);
            }
    
    


     

    Monday, July 13, 2009 6:09 AM
  • Hi,
    Thanks for that.

    What references & Using statements have you added as I get a load of build errors.

    I added in SystemDiagnostics but still have these...

    Error    1    The name 'ExecuteCommandSync' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    16    13    Crypto1
    Error    2    The name 'ConfigurationManager' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    18    17    Crypto1
    Error    3    The name 'emailAddressKey' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    18    50    Crypto1
    Error    4    No overload for method 'ExecuteCommandSyncWithPassphrase' takes '1' arguments    C:\Projects\Crypto1\Crypto1\Program.cs    26    13    Crypto1
    Error    5    The name 'ConfigurationManager' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    32    57    Crypto1
    Error    6    The name 'pgpPathKey' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    32    90    Crypto1
    Error    7    The name 'ConfigurationManager' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    35    36    Crypto1
    Error    8    The name 'pgpPathKey' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    35    69    Crypto1
    Error    9    The name 'TracingHelper' does not exist in the current context    C:\Projects\Crypto1\Crypto1\Program.cs    53    13    Crypto1


    Regards
    Dave
    Monday, July 13, 2009 8:26 AM
  • Got the method
    ExecuteCommandSyncWithPassphrase working now although I did remove the ConfigurationManager.AppSettings[pgpPathKey] and use standard string variables. 

    Is there any chance you could post the other mothid (ExecuteCommandSync)?

    Thanks
    Dave
    Monday, July 13, 2009 9:06 AM
  • Got it working now...




    using System;
    using System.Diagnostics;
    
    namespace FileSystemExample
    {
        class FileExample
        {
    
            public static void EncryptFile(string inputName, string outputName)
            {
                const string commandFormat = @"--yes --batch --encrypt --output {0}  --armour --recipient {1} {2}";
    
                ExecuteCommandSync(string.Format(commandFormat, outputName,
                    "test@test.com",
                    inputName
                    ));
            }
    
            public static void DecryptFile(string inputName, string outputName)
            {
                const string commandFormat = @"--passphrase-fd 0 --batch --output {0} --decrypt {1}";
                ExecuteCommandSyncWithPassphrase(string.Format(commandFormat,outputName, inputName),"mypass");
            }
    
            public static void ExecuteCommandSyncWithPassphrase(string command, string password)
            {
                string path = string.Format(@"{0}\gpg.exe", @"C:\Program Files\GNU\GnuPG");
    
                var procStartInfo = new ProcessStartInfo(path, command)
                {
                    WorkingDirectory =  @"C:\Program Files\GNU\GnuPG\Work", 
                    CreateNoWindow = false,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true
                };
    
                var proc = new Process { StartInfo = procStartInfo };
                proc.Start();
                proc.StandardInput.WriteLine(password);
                proc.StandardInput.Flush();
    
                // Get the output into a string
                string result = proc.StandardOutput.ReadToEnd();
                string error = proc.StandardError.ReadToEnd();
    
                Console.WriteLine(result);
                Console.WriteLine(error);
            }
    
    
            public static void ExecuteCommandSync(string command) 
            {
                string path = string.Format(@"{0}\gpg.exe", @"C:\Program Files\GNU\GnuPG");
                Console.WriteLine(command);
                var procStartInfo = new ProcessStartInfo(path, command)
                {
                    WorkingDirectory = @"C:\Program Files\GNU\GnuPG\Work", 
                    CreateNoWindow = false,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true
                };
    
                var proc = new Process { StartInfo = procStartInfo };
                proc.Start();
    
                //proc.StandardInput.WriteLine(password);
                proc.StandardInput.Flush();
    
                // Get the output into a string
                string result = proc.StandardOutput.ReadToEnd();
                string error = proc.StandardError.ReadToEnd();
    
                Console.WriteLine(result);
                Console.WriteLine(error);
            }
    
            public static void Main()
            {
    
                EncryptFile("DAVE.TXT", "DAVE.ASC");
                DecryptFile("DAVE.ASC", "DAVE_NEW.TXT");
    
            }
        }
    }
    
    
    • Marked as answer by york0001 Monday, July 13, 2009 11:17 AM
    Monday, July 13, 2009 11:14 AM
  • Hi ,

     

    When I am executing the above code ,

     

    getting the out output like this

    --yes --batch --encrypt --output Encrypted.txt  --armour --recipient abc
    @gmail.com test.txt



    You need a passphrase to unlock the secret key for
    user: "abc (inrs) <abc@gmail.com>"
    1024-bit ELG-E key, ID 90C042A4, created 2010-05-03 (main key ID CCD0FB0D)


    gpg: encrypted with 1024-bit ELG-E key, ID 90C042A4, created 2010-05-03
          "abc (inrs) <abc@gmail.com>"
    gpg: public key decryption failed: bad passphrase
    gpg: decryption failed: secret key not available

     

    could you please tell me that when am I doing wrong?

    i saved the test.txt files in c drive. path is C:\test.txt

    where should i save the other files??

    thanks in advance,

    Tuesday, May 11, 2010 6:40 PM
  • Are you executing this from the command line?

     

     

    Wednesday, May 12, 2010 7:25 AM
  • hi,

    I got a problem with the working directory  when decrypting the file,

     

    Is "working directory" location is for saving the decrypted file ??

     

    What is the exact purpose of the working directory?

     

    Here after decrypting the file I am uploading it in to the some other server... But I am not able to do that.

     

    I can only Upload to the server where the encrypted file is located.

    For example if the decrypted file is in ftp:// 123.23.23.23/Test

    downloading to the C:/users/ABC/abc

    when I am trying to upload some other folder, its showing some error like " The remote server returned and error(550):File Unavailable(e.g., File not found, no access).

     

    But if I am using the same folder for downloading , decrypting( working directory), and uploading it is working fine with the same error.

     

    I am really  confused where am I going wrong?

     

    Please reply me ASAP.....

    thanks in advance,

     

     

    Wednesday, July 07, 2010 3:57 PM
  • hi,

    I got a problem with the working directory  when decrypting the file,

    Is "working directory" location is for saving the decrypted file ??

    What is the exact purpose of the working directory?

    Here after decrypting the file I am uploading it in to the some other server... But I am not able to do that.

    I can only Upload to the server where the encrypted file is located.

    For example if the decrypted file is in ftp:// 123.23.23.23/Test

    downloading to the C:/users/ABC/abc

    when I am trying to upload some other folder, its showing some error like " The remote server returned and error(550):File Unavailable(e.g., File not found, no access).

    But if I am using the same folder for downloading , decrypting( working directory), and uploading it is working fine with the same error.

    I am really  confused where am I going wrong?

    Please reply me ASAP.....

    thanks in advance,

     

     

    Hi, 

    WorkingDirectory is just a property which points to a local starting/working directory.  In fact this program does everything locally 

    and nothing over the network.  

    From the Class definition:

        // Summary:

            //     Gets or sets the initial directory for the process to be started

            // Returns:

            //     The fully qualified name of the directory that contains the process to be

            //     started. The default is an empty string ("").

     

    Why not set two different "WorkingDirectory" properties, one for encrypting and one for decrypting? 

     

    HTH. 

     

     

     

    Wednesday, July 07, 2010 4:24 PM
  • Hi,

     

    I dont need to encrypt here, have to do only decryption.

    I already have a encrypted file from the some remote server, I am downloading that file, decrypting it and then uploading to the another remote server.

     

    could you please explain me more clearly??

     

    thank you.

     

     

    Wednesday, July 07, 2010 4:42 PM
  • Can you post your code and highlight which part is failing and also post any error messages. 

     

    Thursday, July 08, 2010 9:48 AM
  • Hi ,

     

    When I am executing the above code ,

     

    getting the out output like this

    --yes --batch --encrypt --output Encrypted.txt  --armour --recipient abc
    @gmail.com test.txt



    You need a passphrase to unlock the secret key for
    user: "abc (inrs) <abc@gmail.com>"
    1024-bit ELG-E key, ID 90C042A4, created 2010-05-03 (main key ID CCD0FB0D)


    gpg: encrypted with 1024-bit ELG-E key, ID 90C042A4, created 2010-05-03
          "abc (inrs) <abc@gmail.com>"
    gpg: public key decryption failed: bad passphrase
    gpg: decryption failed: secret key not available

     

    could you please tell me that when am I doing wrong?

    i saved the test.txt files in c drive. path is C:\test.txt

    where should i save the other files??

    thanks in advance,

    You also need to substitute abc@gmail.com for the email that was use to encrypt the file.  
    Thursday, July 08, 2010 10:16 AM
  • Previous problem is solved.

    I am using the direct path of the decrypted file and encrypted file when I am working the complete program.

    I am just using decryption program alone in my project, when I am running in the client server it is not running properly  and showing error

     

    system.componentModel.win32Exception: the system cannot find the path specified at System.Diagnostics.process.startwithcreate(processstartInfo startInfo)

       at System.Diagnostics.process.start()

       at Filesystemexample.Fileexample .ExecutecommandSynchWithPassphrase(string command, string password)

    in c:\practiceprojects\Filesystemexample\program.cs line 86

     

    And here is my code,

     

     public static void Main()

            {

               DecryptFile( "extract_CES_SAE_v2_p0004674dvke_20100624183423.txt.pgp", "abc6.txt");         

                System.Threading.Thread.Sleep(6000);

            }

     

            public static void DecryptFile(string inputName, string outputName)

            {

                const string commandFormat = @"--passphrase-fd 0 -o {0}  --decrypt {1}";

     

                ExecuteCommandSyncWithPassphrase(string.Format(commandFormat, outputName, inputName), "emaxim123");

            }

     

            public static void ExecuteCommandSyncWithPassphrase(string command, string password)

            {

                string path = string.Format(@"{0}\gpg.exe", @"C:\Program Files\GNU\GnuPG");

     

     

                var procStartInfo = new ProcessStartInfo(path, command)

                {

                    WorkingDirectory = "C:\\upload\\",

                    CreateNoWindow = false,

                    UseShellExecute = false,

                    RedirectStandardOutput = true,

                    RedirectStandardError = true,

                    RedirectStandardInput = true

                };

                try

                {

                    var proc = new Process { StartInfo = procStartInfo };

    LINE 86:    proc.Start();

                    proc.StandardInput.WriteLine(password);

                    proc.StandardInput.Flush();

                    //proc.WaitForExit(3500);

     

                    // Get the output into a string

                    string result = proc.StandardOutput.ReadToEnd();

                    string error = proc.StandardError.ReadToEnd();

                    //Console.WriteLine(result);

                    //Console.WriteLine(error);

                }

     

                catch (Exception ex )

                {

                    Console.WriteLine(ex.ToString());

                }

     

    Could you please reply me ASAP??

     

    Thank you

     

     

    Friday, July 09, 2010 1:13 AM
  • LOOKING AT THIS LINK IS AN EXAMPLE OF HOW TO DO IT, COULD TAKE THE CODE AS AN EXAMPLE AND PUBLISH DLL DLL AND THEN THAT APPEAR ON YOUR PROJECT

    http://www.systemdeveloper.info/2013/11/decrypt-files-encrypted-with-gnupg-from.html
    Tuesday, December 24, 2013 4:40 PM