【问题标题】:php GnuPG decrypt times outphp GnuPG解密超时
【发布时间】:2014-05-11 19:28:32
【问题描述】:

我正在尝试使用 php GnuPG 函数使用私钥解密 gpg 文件。但是,当尝试解密时,看起来 php 只是挂起或永远完成。我正在尝试解密一个包含一句话的简单测试文件。

我可以离线解密文件(例如使用 GNU Privacy Assistant)。

我想我已经设置权限了-

-bash-4.1$ gpgconf --list-dirs

/home/jdoe/.gnupg/gpg.conf,权限:0770
/home/jdoe/.gnupg/pubring.gpg~,烫发:0770
/home/jdoe/.gnupg/secring.gpg,权限:0660
/home/jdoe/.gnupg/private-keys-v1.d,权限:0700
/home/jdoe/.gnupg/random_seed,权限:0600
/home/jdoe/.gnupg/pubring.gpg,权限:0770
/home/jdoe/.gnupg/trustdb.gpg,权限:0770

但是,如果我将一个新文件写入“/home/jdoe/.gnupg/”,它会得到 644 个权限(不确定这是否重要)。

/home/jdoe/.gnupg/xxxtest.txt.gpg,权限:0644

我(认为)我已成功导入私钥。 KeyInfo 如下。相关密钥的指纹和密钥 ID 为 888(我已将它们的实际值替换为 888)。我包括所有相关的密钥(我已将不相关的指纹/密钥信息替换为 777)。

$info = $gpg->keyinfo(''); 回声“关键信息:”。 print_r($info, true);

Array ( [0] => Array ( [disabled] => [expired] => [revoked] => [is_secret] => [can_sign] => 1 [can_encrypt] => 1 [uids] => Array ( [0] => 数组 ( [name] => ApacheTest [comment] => 测试 [email] => apache@localhost [uid] => ApacheTest (Testing) [撤销] => [无效] => ) [ subkeys] => Array ( [0] => Array ( [fingerprint] => 777 [keyid] => 777 [timestamp] => 1203433839 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] => [can_sign] => 1 [disabled] => [expired] => [revoked] => ) [1] => Array ( [fingerprint] => 777 [keyid] => 777 [timestamp] => 1203433840 [ expires] => 0 [is_secret] => [invalid] => [can_encrypt] => 1 [can_sign] => [disabled] => [expired] => [revoked] => ) ) ) [1] => 数组( [disabled] => [expired] => [revoked] => [is_secret] => [can_sign] => 1 [can_encrypt] => 1 [uids] => Array ( [0] => Array ( [name] => John Doe [comment] => [email] => john.doe@example.com [uid] => John Doe [revoked] => [invalid] => ) ) [subkeys] => Array ( [0] => 数组([指纹] => 888 [keyid] => 888 [timestamp] => 1224013510 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] => [can_sign] => 1 [disabled] => [expired] => [已撤销] => ) [1] => 数组 ( [fingerprint] => 777 [keyid] => 777 [timestamp] => 1224013510 [expires] => 0 [is_secret] => [invalid] => [can_encrypt] = > 1 [can_sign] => [disabled] => [expired] => [revoked] => ) ) ) )

我的问题是,当尝试使用下面的代码解密时,看起来 php 只是挂起或需要永远完成(实际上超过了 max_execution_time,但没有显示有关它的错误消息)。

$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION); 
putenv("GNUPGHOME=/home/jdoe/.gnupg");

$encryptedContent = file_get_contents($filePathAndName);

$pw = [];
$fingerprint = [];
if($gpg->adddecryptkey($recipient, $pw)) {
    echo "Add decrypt key returned true.";
} else {
    echo "Could not add decrypt key. GPG error: " . $gpg -> geterror();
}

//I know we get to this spot
try {
    $plaintext = $gpg->decrypt($encryptedContent);
    echo '<pre>' . $plaintext . '</pre>';
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}

关于为什么这不起作用的任何想法?非常感谢。

=============== ls -la /home/jdoe/.gnupg 的输出


drwxrwx--- 3 jdoe apache 4096 3 月 31 日 23:45。
drwxr-xr-x 19 jdoe root 12288 Apr 1 09:39 ..
-rwxrwx--- 1 jdoe apache 9188 3 月 28 日 15:36 gpg.conf
drwx----- 2 apache apache 4096 Mar 31 21:26 private-keys-v1.d
-rwxrwx--- 1 apache apache 2479 3 月 31 日 21:26 pubring.gpg
-rwxrwx--- 1 apache apache 913 3 月 31 日 20:28 pubring.gpg~
-rw------- 1 apache apache 600 3 月 31 日 20:32 random_seed
-rw-rw---- 1 jdoe apache 1978 年 3 月 28 日 21:05 secring.gpg
-rwxrwx--- 1 apache apache 10 Mar 31 20:28 test.txt
-rwxrwx--- 1 jdoe apache 1200 3 月 31 日 20:28 trustdb.gpg
-rw-r--r-- 1 apache apache 347 Mar 31 23:30 xxxtest.txt.gpg

你能从命令行解密文件吗?需要多长时间?

将向您提供此信息(与 SA 合作,我只能通过 ftp 访问机器)。

试试增加PHP的报错?

已经完成...它只是旋转(我认为这意味着它超时,out exit_on_timeout 已关闭)。我已经尝试了 10 分 30 秒的超时。结果是一样的。我们正在解密的测试文件少于 100 个字符。

您可能想尝试不设置主目录,而是使用 import($keydata) 导入密钥

同样的结果

尝试设置不同的主目录?

我创建了 /home/jdoe/.gnupg/temp,chmod 权限为 777。我将其设置为 gpg 的主目录。我试图导入私钥。但是, $gpg->keyinfo('') 什么也不返回。这次尝试 $gpg->adddecryptkey 时,它失败并出现此错误 - “未捕获异常 'Exception' 并带有消息 'get_key failed'”。

谢谢

【问题讨论】:

  • 请添加ls -la /home/jdoe/.gnupg的输出。您可以从命令行解密文件吗?需要多长时间?有没有尝试增加 PHP 的错误报告?
  • 我在上面添加了这些信息。非常感谢。
  • GnuPG 可能不像组写权限。您可能想尝试不设置主目录,而是使用import($keydata) 将密钥导入 Web 服务器的 GnuPG 目录,或者创建一个他拥有且仅对该用户具有访问权限的密钥。 $gpg-&gt;adddecryptkey($fingerprint, $pw); 的结果是什么?我不认为这个函数会抛出错误消息,而是在错误时返回false
  • 谢谢 - 我添加了上面的结果 + 我将代码更改为“捕获”返回的 false。 (到目前为止没有运气)

标签: php gnupg


【解决方案1】:

如果有人仍然面临这个问题(就像我一样),请阅读:

从 gnupg 版本 2 开始,无法再传递纯密码。该参数被简单地忽略。相反,如果 php 在 cli 模式下运行,则会启动 pinentry 应用程序。在 cgi 或 apache 模式下,打开密钥会失败。 最简单的解决方案是使用没有密码的密钥。

来自:http://php.net/manual/en/function.gnupg-decrypt.php

在我删除密码之前,我通过 cron 运行的 php 脚本总是无法解密。我尝试使用不带密码的密钥,对我来说效果很好。

干杯!

【讨论】:

    【解决方案2】:

    我今天遇到了和你一样的问题。关于如何解密一个简单文件的无休止的故障排除。即使我正在解密一个 568 字节的文件,PHP 也会无休止地挂起。解决方案是不使用内置的 PHP 函数,而是使用 PEAR Crypt_GPG 库

    首先安装库(这里的另一个答案中建议的 1.4.0b4):

    pear install Crypt_GPG-1.4.0b4
    

    完成后,进入一个 php 文件并使用以下代码作为示例:

    set_include_path("/usr/share/pear"); //ADD PEAR FOLDER TO INCLUDE PATH
    require_once 'Crypt/GPG.php'; //INCLUDE PEAR LIBRARY
    $options = array('homedir' => '/tmp'); //KEYRING DIRECTORY
    $gpg = new Crypt_GPG($options); //MAKE NEW GPG OBJECT
    

    现在,熟悉一下 Crypt_GPG 类:http://pear.php.net/package/Crypt_GPG/docs/latest/Crypt_GPG/Crypt_GPG.html

    别忘了添加你的公钥(只需要运行一次):

    $gpg->importKey(file_get_contents("/path/to/public-key.key"));
    

    列表键:

    $keys = $gpg->getKeys();
    print_r($keys);
    

    向您的 GPG 对象添加解密密钥

    $gpg->addDecryptKey($keys[0],"key passphrase");
    

    现在,解密你的文件:

    file_put_contents($unencrypted_file,$gpg->decrypt(file_get_contents($encrypted_file)));
    

    我希望这对人们有所帮助,因为哇……我花了一整天的时间试图弄清楚如何用 PHP 解密文件。我可以在大约 5 分钟内用 C# 完成的事情。

    【讨论】:

      【解决方案3】:

      我在切换到新服务器时遇到了同样的问题。我的问题是新服务器使用的是 gpg2,而 Crypt_GPG 的当前稳定版本(1.3.2)不支持这个。 对我来说,它也解决了升级 Crypt_GPG 的新 beta 版本 (1.4.0b4) 的问题。

      【讨论】:

        猜你喜欢
        • 2018-11-28
        • 2013-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-08
        相关资源
        最近更新 更多