我们收到来自第三方的GPGencryption文件。 我正在修改一个C#程序来查找encryption文件,解密它们,并删除encryption的文件。 这一切除了在解密部分,它提示一个phassphrase; 我知道密码,它input时工作。 我需要在命令中传递密码,所以提示不会出现。
string CommandText = string.Format("echo {0}|gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase-fd 0 -o {3} -d {4}", passPhrase, publicKeyRingPath, secretKeyRingPath, outputFullPath, encryptedFilePath);
我也试过了:
string CommandText = string.Format("gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase {0} -o {3} -d {4}", string CommandText = string.Format("gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase-fd {0} -o {3} -d {4}",
以及其他几个变化。
这是运行Windows 2.1.0.57899的GnuPG
如果问题在别处,那么主要是由我的前任编写的代码:
public bool decryptInputFile(string encryptedFilePath, string outputFullPath, out string message) { message = "decryptInputFile: Started"; try { ProcessStartInfo psi = new ProcessStartInfo("cmd.exe") { CreateNoWindow = true, UseShellExecute = true, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, WorkingDirectory = decryptPath, }; message = "decryptInputFile: PSI Initialized"; using (Process process = Process.Start(psi)) { string CommandText = string.Format("echo {0}|gpg.exe --keyring {1} --secret-keyring {2} --batch --yes --passphrase-fd 0 -o {3} -d {4}", passPhrase, publicKeyRingPath, secretKeyRingPath, outputFullPath, encryptedFilePath); process.StandardInput.WriteLine(CommandText); process.StandardInput.Flush(); process.StandardInput.Close(); process.WaitForExit(); process.Close(); process.Dispose(); message = "decryptInputFile: Success"; //These processes don't close and it keeps the file from being deleted. foreach (Process P in Process.GetProcessesByName("gpg")) { P.Kill(); } foreach (Process P in Process.GetProcessesByName("gpg2")) { P.Kill(); } } } catch (Exception x) { // If there was an error, we're going to eat it and just let the user know we failed. message = "decryptInputFile: Error: " + x.Message; string errMessage = "ERROR: could not decrypt. " + x.Message + "\r\n"; File.AppendAllText(System.Configuration.ConfigurationSettings.AppSettings["LogPath"], errMessage); return false; } if (File.Exists(outputFullPath) && File.Exists(encryptedFilePath)) { File.Delete(encryptedFilePath); } return File.Exists(outputFullPath); }
您正在使用GnuPG 2,它只允许--passphrase*
选项和--batch
一起使用。
--batch
--passphrase*
选项旨在用于脚本。 GnuPG 2限制它们(可能是为了将它们慢慢弃用)到GnuPG不执行任何交互(例如,请求您的密码或其他“对话”)的--batch
模式。
虽然这仍然是可能的,但是最好使用gpg-agent
的密码预设来代替,它允许您从应用程序代码中完全删除密码。 请注意--passphrase
的含义(只要GnuPG正在运行,系统上的所有用户都可以读取它)和--passphrase-file
(密码存储在硬盘上,注意权限)。
使用GnuPG 2的首选方法是预设GnuPG严重依赖的gpg-agent
的密码短语; 在GnuPG 2.1的情况下,甚至可以完全处理私钥和密码操作。
但是,为了解救,GnuPG 2带来了一个新的工具gpg-preset-passphrase
。 在Debian Linux中,它隐藏在/usr/lib/gnupg2/
,我不知道它存储在Windows中的位置。
从man gpg-preset-passphrase
:
gpg-preset-passphrase
是一个实用工具,用于通过密码短语来运行正在运行的gpg-agent
的内部缓存。 它主要用于无人值守的机器,在那里通常的pinentry
工具可能不被使用,并且在机器启动时给出使用钥匙的密码。[…]
gpg-preset-passphrase
是这样调用的:gpg-preset-passphrase [options] [command] cacheid
cacheid
是40个字符的十六进制字符keygrip,用于标识要设置或清除密码的密钥。 […]必须给出以下命令选项之一:
--preset Preset a passphrase. This is what you usually will use. gpg-preset-passphrase will then read the passphrase from stdin.
总结一下,当为你的应用程序初始化GnuPG(并在与配置的缓存时间相对应的intervalls中)时,运行gpg-preset-passphrase --preset [fingerprint]
,它将从标准输入读取密码,或者另外使用--passphrase passphrase
选项直接在您的查询中设置它。 请注意,同时使用echo或--passphrase
方法时,其他系统用户可能通过列出进程来获取密码短语; 更好的直接从C#写入进程的标准输入。