我正在尝试在运行 XAMPP 的 Windows 平台上使用 PHP 进行 GPG 加密。
网络服务器是 Apache,运行 PHP 5.2.9。我正在使用 GPG4Win 2.0.4。
我已经成功地从命令行运行了 encrypt 命令。我已经更改了收件人和主机名。
C:\>C:\PROGRA~1\GNU\GnuPG\pub\gpg.exe --encrypt --homedir C:\DOCUME~1\reubenh.AD\APPLIC~1\gnupg --recipient name@host.com --armor < test.txt > test.enc.txt
在 PHP 中,我使用 proc_open(),因此我可以将要加密的内容直接通过管道传输到进程,并使用 stdout 管道获取输出。
以下是代码片段:
$cmd = Configure::read('Legacy.GPG.gpg_bin').' --encrypt '.
'--homedir '.Configure::read('Legacy.GPG.gpg_home').' '.
'--recipient '.Configure::read('Legacy.MO.gnugp_keyname').' '.
'--local-user '.'me@host.com'.' '.
'--armor --no-tty --batch --debug-all';
error_log('Encrypting Command line is '.$cmd);
$descriptors = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('file', LOGS.'gpg.log', 'a')
);
$process = proc_open($cmd, $descriptors, $pipes);
if (is_resource($process)) {
error_log(print_r($pipes, true));
list($stdin, $stdout) = $pipes;
error_log('Have pipes');
error_log('body length is '.strlen($this->request['body']));
$ret = fwrite($stdin, $this->request['body'], strlen($this->request['body']));
error_log($ret.' written');
error_log('before fclose()');
fclose($stdin);
error_log('Done with input');
$encryptedData = '';
while(!feof($stdout)) {
$line = fgets($stdout);
error_log('Line read:'.error_log(print_r($line, true)));
$encryptedData .= $line;
}
fclose($stdout);
$return = proc_close($process);
error_log('Encryption process returned '.print_r($return, true));
if ($return == '0') { // ... next step is to sign
第一个 error_log() 语句生成的命令是:
C:\PROGRA~1\GNU\GnuPG\pub\gpg.exe --encrypt --homedir C:\DOCUME~1\reubenh.AD\APPLIC~1\gnupg --recipient name@host.com --local-user me@host.com --armor --no-tty --batch --debug-all
实际运行似乎达到了“有管道”。在那之后,它就停止了。
我还可以在 Process Explorer 中看到 gpg.exe 也生成了一个 gpg2.exe。我怀疑是这个我没有句柄的 gpg2.exe 正在等待输入,而不是我调用的原始 gpg.exe。
我试过直接调用 gpg2.exe,但仍然生成了一个子 gpg2.exe。
我宁愿使用 proc_open(),并避免使用磁盘 I/O 来提供内容和获取输出,因为这将在网络服务器上运行,而 proc_open() 将让我不必费心生成唯一文件,然后必须清理它们。