gpt4 book ai didi

php - 如何在 web 服务器下的 Windows 平台上通过 PHP 进行 gpg 加密?

转载 作者:可可西里 更新时间:2023-11-01 12:05:30 28 4
gpt4 key购买 nike

我正在尝试在运行 XAMPP 的 PHP 中的 Windows 平台上进行 GPG 加密。

Web 服务器是 Apache,运行的是 PHP 5.2.9。我正在使用 GPG4Win 2.0.4。

我已经成功地从命令行运行加密命令。我已经更改了收件人和主机名。

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

实际运行似乎达到“Have pipes”。之后,它就停止了。

我还可以在 Process Explorer 中看到,gpg.exe 还会生成一个 gpg2.exe。我怀疑是我没有句柄的这个 gpg2.exe 正在等待输入,而不是我调用的原始 gpg.exe。

我已尝试直接调用 gpg2.exe,但仍生成子 gpg2.exe。

我宁愿使用 proc_open(),并避免使用磁盘 I/O 来提供内容和获取输出,因为这将在网络服务器上运行,而 proc_open() 将使我不必费心生成唯一文件,然后必须清理它们。

最佳答案

我最终做出了妥协,以使解决方案最初“有效”,尽管我对它的完成方式不是很满意。

问题似乎分为两部分。

第一部分是进程在尝试签名时会挂起,并使用 --passwd-fd 选项。如果我离开这个选项,我会通过网络服务器的交互特性得到一个提示,手动输入,一切都会好起来的。对于无人值守的应用程序,解决方法是简单地没有密码。我在各种 GnuPG 论坛上看到过这样的建议,即如果您的密码短语将作为纯文本存储在与私钥相同的机器上,那么您也可以放弃伪装并且没有伪装。目前没有密码短语有效。

第二部分是输入太大。神奇的数字似乎是 72kb。使用 proc_open 和标准管道的任何要加密的有效负载似乎都不起作用。因此,我选择暂时将有效负载写入一个文件,由 proc_open 读取。见如下:

$tmpfile = tmpfile();
fwrite($tmpfile, $this->request['body']);
fseek($tmpfile, 0);

$cmd = '...'; // similar to question command, but with --sign --encrypt and no --passphrase-fd

$descriptors = array(
0 => $tmpfile,
1 => array('pipe', 'w'),
2 => array('file', LOGS.'gpg.log', 'a')
);

$options = array('bypass_shell' => true);

$process = proc_open($cmd, $descriptors, $pipes, null, null, $options);
if (is_resource($process)) {
stream_set_blocking($pipes[1], 0);

fclose($tmpfile);

$encryptedData = '';
$line = fgets($pipes[1]);
while (!feof($pipes[1])) {
$encryptedData .= $line;
$line =fgets($pipes[1]);
}

fclose($pipes[1]);

$return = proc_close($process);

if ($return = '0') {
// success processing
}
}

我选择不使用 list() = $pipes,因为实际上只有标准输出管道会在数组中返回。

如果有人在 Windows 环境中使用过 GPG 和 PHP,我非常欢迎听到一些东西,即使它已经过去了很多年。

关于php - 如何在 web 服务器下的 Windows 平台上通过 PHP 进行 gpg 加密?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5073126/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com