bash 如何强制 GPG 接受来自 STDIN 的输入而不是尝试打开文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6981589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I force GPG to accept input from STDIN instead of trying to open a file?
提问by Axinar
I am trying to incorporate GPG clear-signing of text in a string in a PHP script. I can cause GPG to encrypt text in a string like this:
我正在尝试在 PHP 脚本的字符串中加入 GPG 明确签名的文本。我可以让 GPG 像这样加密字符串中的文本:
$encrypted = shell_exec("echo '$text' | gpg -e -a -r [email protected] --trust-model always");
and that works perfectly, with the encrypted text being sent to the $encrypted variable. This proves GNUPGHOME and GNUPG are set up correctly.
这非常有效,加密文本被发送到 $encrypted 变量。这证明 GNUPGHOME 和 GNUPG 设置正确。
However, when I try to produce a clear-signed message in the same way with this:
但是,当我尝试以与此相同的方式生成明确签名的消息时:
$text = "googar";
$signature = exec("echo $passphrase | gpg -v --clearsign --no-tty --passphrase-fd 0 '$text' 2>&1 1> /dev/null", $output);
I am returned this error:
我返回此错误:
... string(51) "gpg: can't open `googar': No such file or directory"
[3]=>
string(46) "gpg: googar: clearsign failed: file open error"
}
This error is returned with or without the single quotes around the $text variable.
此错误在 $text 变量周围带有或不带有单引号的情况下返回。
How can I force GPG or shell_exec to treat $text as a pipe instead of it looking for a file?
如何强制 GPG 或 shell_exec 将 $text 视为管道而不是查找文件?
I need to echo the passphrase in this way (I know, its 'horribly insecure' because GPG has no way to pass in a passphrase as a variable on the command line.
我需要以这种方式回显密码(我知道,它“非常不安全”,因为 GPG 无法在命令行上将密码作为变量传递。
回答by vstm
You could use proc_openand create a separate file descriptor for your password:
您可以使用proc_open并为您的密码创建一个单独的文件描述符:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w"),
3 => array("pipe", "r"),
);
$pipes = false;
$process = proc_open("gpg -v --clearsign --no-tty --passphrase-fd 3", $descriptorspec, $pipes);
if(is_resource($process)) {
fwrite($pipes[3], $passphrase);
fclose($pipes[3]);
fwrite($pipes[0], $text);
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$retval = proc_close($process);
echo "retval = $retval\n";
echo "output= $output\n";
echo "err= $stderr\n";
}
回答by jfg956
You could use process substitution:
您可以使用流程替换:
echo $passphrase | gpg -v --clearsign --no-tty --passphrase-fd 0 <(printf '$text') 2>&1 1> /dev/null
^^ ^
This will make gpg thinks it is reading data from a file, but the file will be a temporary named pipe which input will be printf '$text'.
这将使 gpg 认为它正在从文件中读取数据,但该文件将是一个临时命名管道,其输入将为printf '$text'.

