php 我怎样才能强制GPG接受来自STDIN的输入而不是尝试打开一个文件?

jaql4c8m  于 2023-04-04  发布在  PHP
关注(0)|答案(2)|浏览(119)

我试图在PHP脚本中将GPG的明文签名合并到字符串中。我可以使GPG加密字符串中的文本,如下所示:

$encrypted = shell_exec("echo '$text' | gpg -e -a -r foo@bar.com --trust-model always");

这工作得很好,加密的文本被发送到$encrypted变量。这证明GNUPGHOME和GNUPG被正确设置。
然而,当我尝试以同样的方式生成一个明确签名的消息时:

$text = "googar";

$signature = exec("echo $passphrase | gpg -v --clearsign --no-tty --passphrase-fd 0 '$text' 2>&1 1> /dev/null", $output);

我得到这个错误:

... string(51) "gpg: can't open `googar': No such file or directory"
[3]=>
string(46) "gpg: googar: clearsign failed: file open error"
}

无论$text变量是否带单引号,都会返回此错误。
如何强制GPG或shell_exec$text视为管道,而不是查找文件?
我需要以这种方式回显密码。我知道,这是“非常不安全的”,因为GPG无法在命令行中将密码作为变量传递。

yhxst69z

yhxst69z1#

您可以使用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";
}
vfhzx4xs

vfhzx4xs2#

可以使用process substitution

echo $passphrase | gpg -v -o- --clearsign --passphrase-fd 0 <(printf "$text")

这将使GPG认为它正在从文件中阅读数据,但该文件将是一个临时命名管道,其输入将是printf "$text"
-o-导致GPG将消息及其签名写入标准输出。

相关问题