Я пытаюсь включить прозрачное подписание текста GPG в строке в скрипте PHP. Я могу заставить 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" }
Эта ошибка возвращается с или без одинарных кавычек вокруг текстовой переменной $.
Как заставить GPG или shell_exec обрабатывать $ text как канал вместо поиска файла?
Мне нужно эхо кодовую фразу таким образом (я знаю, его «ужасно небезопасно», потому что GPG не имеет возможности передавать в качестве ключевой фразы в качестве переменной в командной строке.
Вы можете использовать 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"; }
Вы можете использовать замену процесса:
echo $passphrase | gpg -v --clearsign --no-tty --passphrase-fd 0 <(printf '$text') 2>&1 1> /dev/null ^^ ^
Это заставит gpg думать, что он считывает данные из файла, но файл будет временным именованным каналом, для ввода которого будет printf '$text'
.