GPG解密失败,提示无私钥错误。

61

我有一个gpg .key文件,用作解密.dat.pgp文件的密码。使用以下命令,在一台具有相同.key文件的服务器上成功解密了加密的.data.pgp文件

cat xxx_gpg.key | /usr/bin/gpg --batch --quiet -o xxx.dat --passphrase-fd O -d xxx.dat.pgp

但是,当我将相同的密钥移动到另一个服务器xxx_gpg.key并运行相同的命令时,我会收到以下错误信息 -

gpg: decryption failed: No secret key

编辑:

我发现在一台服务器上执行gpg --list-secret-keys会返回一些数据,但是在另一台服务器上却没有任何结果。

我们如何配置秘钥?


每台机器上都需要安装完全相同版本的gpg吗? - Xen2050
在两个地方使用相同的 GPG 版本 - 2.0.14。 - fortm
嗯。显然,“--passphrase-fd”只读取“第一行”,这些在每个系统上看起来相同吗?也许不同的shell会以不同的方式转换或管道传输它们?刚刚看到一个情况,其中反斜杠被read所“吃掉”了... - Xen2050
1
口令词在所有地方都相同,我发现唯一的区别是我在帖子中编辑的内容,这使得 gpg --list-secret-keys 的列表不同。 - fortm
我原本以为你在使用“传统”的加密方式,早该想到公钥/私钥加密了,但是我对“密钥文件”和“秘密密钥”搞混了。我会发布一些选项/想法。 - Xen2050
这种情况发生在仅使用ssb子密钥(sec密钥正常工作)的gpg2.1.5加密文件中,gpg2.1.5无法解密自己的输出,但gpg1.4能够解密相同的数据。在win7上。 - mosh
12个回答

52

我刚刚在Arch Linux中使用gpg CLI时遇到了这个问题。我需要终止已有的“gpg-agent”进程,然后一切都恢复正常(当您再次调用gpg命令时,应该会自动启动一个新的gpg-agent...)。

  • 编辑:如果进程无法重新加载(例如在一分钟内),请在终端中执行gpg-agent和/或重新启动...

1
这正是我的问题所在,解决方法是 - 我已经使用gpg一段时间了,但显然现在默认启用了代理?也许是在我现在(无意中)运行的Ubuntu 17.04中。 :-) 我想它仍然存在一些错误。 - moodboom
8
在我的 macOS 上也遇到了同样的问题和解决方法。之前的一次解密出了些问题,导致了上述错误。 - Sam A. Horvath-Hunt
6
补充一下,在 macOS 上,使用命令 gpgconf --kill gpg-agent 可以关闭 gpg-agent,无需特别重启代理。 - Marius Hofert
对我来说,我的终端太小了。将其放大以便在gpg中输入密码短语就可以解决这个问题。这很快就会变得很烦人。我相信有一种方法可以将密码短语保存在某个地方。但如果有一个适用于较小终端屏幕的界面而不仅仅是导致命令失败,那就太好了... - Kevin Y

29

我试图使用aws-vault,它使用passgnupg2(gpg2)。 我在运行WSL2的Ubuntu 20.04上尝试了上述所有解决方案,最终我不得不做一件事 -

$ rm ~/.gnupg/S.*                    # remove cache
$ gpg-connect-agent reloadagent /bye # restart gpg agent
$ export GPG_TTY=$(tty)              # prompt for password
# ^ This last line should be added to your ~/.bashrc file

这个解决方案的来源是一篇日文博客文章,幸运的是有Google翻译 :)


2
同样适用于在WSL2中运行的Ubuntu 18.04。 - Tschitsch
也适用于 macOS。 - d70rr3s

28

看起来密钥不在另一台机器上,所以即使有正确的密码短语(从文件中读取),也无法使用。

以下选项应该可行,要么将密钥环(可能只需要秘密密钥环,但公钥环是公开的)复制到另一台机器上,

要么导出私钥,然后在另一台机器上导入它。

man gpg中的一些有用选项:

--export
导出所有 keyrings 中的所有密钥(默认keyrings和通过选项--keyring注册的keyrings),或如果给定至少一个名称,则导出给定名称的密钥。新的 keyring 写入 STDOUT 或使用 --output 选项给定的文件。与 --armor 一起使用以发送邮件的密钥。

--export-secret-keys
--export 相同,但导出私钥。

--import
--fast-import
导入/合并密钥。这将添加所给密钥到密钥环中。快速版本当前只是一个同义词。

也许还有

--keyring file
将文件添加到当前密钥环列表中。如果文件以波浪符和斜杠开头,则会将其替换为 $HOME 目录。如果文件名不包含斜杠,则假定它在 GnuPG 主目录中(如果未使用 --homedir 或 $GNUPGHOME,则为 "~/.gnupg")。

请注意,这将添加一个 keyring 到当前列表中。如果要仅使用指定的 keyring,请同时使用 --keyring--no-default-keyring

--secret-keyring file
--keyring 相同,但用于密钥环的秘密密钥。


5
简化版:

从另一台机器导入密钥:

gpg --export ${ID} > public.key gpg --export-secret-key ${ID} > private.key

将这些文件复制到其他机器上,然后执行:

gpg --import public.key gpg --import private.key

来自 https://unix.stackexchange.com/questions/184947/how-to-import-secret-gpg-key-copied-from-one-machine-to-another 的参考。

- Yaroslav Nikitenko
1
以上正是我尝试过并导致了OP发布的错误信息。 - aioobe
@aioobe 正确(秘密)密钥不应该被其他gpg获取或查看。你是指你尝试了YaroslavNikitenko的命令吗?我还没有测试过它们,但它们看起来很好,只要$ID是正确的。我会尝试使用--output而不是--export,但这不应该有影响。导出秘密密钥然后导入它应该可以工作,在--list-keys(-k或-K)中显示吗?或者复制整个密钥环文件,然后使用--keyring肯定可以...我曾经遇到过gpg-agent无法读取密码短语的问题,即使使用--passphrase-file,或者用一些-v替换--quiet--batch - Xen2050
我做了 --export / --import 的事情。问题实际上是我们在“接收”(--import)机器上使用的是 gpg 而不是 gpg2。不能说为什么。它们应该是兼容的,但似乎有些情况下它们并不兼容。 - aioobe
这很令人失望,希望它只是一个可以迅速修复的小bug,向后兼容是一个巨大的优势。 - Xen2050

17

如果终端窗口太小,使用实用程序pass会出现此错误!

只需将终端窗口增高几行。

非常令人困惑。

对怀疑论者的解释。 当使用pinentry的curses版本时,会出现这个问题,如这里所述:"由于使用 curses 绘制对话框的方式, pinentry-curses 仅在高度大于10行的终端上起作用"


1
我认为你提出了一个很有价值的观点。忽略这一点可能会导致不必要的混淆。所以我再次投了你一票 :) - m4110c
3
哦,天哪,我从来没有想过那可能会成为一个问题。这完全解决了我的问题。 - Meir Gabay
你应该得到一百万个赞。我也遇到了这个问题,于是我谷歌搜索并找到了你的答案。最终我成功地解决了这个问题,而且非常顺利。 - emory
如果您使用su - yourUser并尝试使用/usr/bin/pass,但yourUser不拥有tty,则它将无法工作。 - fraff

8
您有时候在使用安装了GPG 2.x的系统上,尝试解密一个秘密时,如果您在不同的用户下使用su,也会出现此错误。已经有人针对RHEL 6报告了这个问题,但目前还没有可用的修复方法;显然,这是由于GPG 2.x中的某些设计决策造成的。报告中建议的一种解决方法是在tmux或screen会话中运行解密操作。更多阅读内容请参见此处

4

3

以下步骤适用于我。

创建gpg密钥。 gpg --gen-key --homedir /etc/salt/gpgkeys

导出公钥、私钥和私有子密钥。

gpg --homedir /etc/salt/gpgkeys --export test-key > pub.key
gpg --homedir /etc/salt/gpgkeys --export-secret-keys test-key > sec.key
gpg --homedir /etc/salt/gpgkeys --export-secret-subkeys test-key > sub.key

现在使用以下命令导入密钥。

gpg --import pub.key
gpg --import sec.key
gpg --import sub.key

确认密钥是否已导入。

gpg --list-keys
gpg --list-secret-keys

创建一个样本文件。

echo "hahaha" > a.txt

使用导入的密钥加密文件

gpg --encrypt --sign --armor -r test-key a.txt

要解密文件,请使用以下命令。

gpg --decrypt a.txt.asc


3

当从一台机器迁移至另一台机器时-

  1. 检查两个系统之间的gpg版本和支持的算法。

    gpg --version

  2. 检查两个系统上是否存在密钥。

    gpg --list-keys

    pub 4096R/62999779 2020-08-04 sub 4096R/0F799997 2020-08-04

    gpg --list-secret-keys

    sec 4096R/62999779 2020-08-04 ssb 4096R/0F799997 2020-08-04

检查其他计算机上是否存在相同的密钥ID。仅需要秘密密钥(sec)和秘密子密钥(ssb)来进行解密操作。

如果该密钥不在另一台计算机上,请从拥有该密钥的计算机中将密钥导出到文件中,然后通过scp将该文件传输到缺少该密钥的计算机上,并在该计算机上导入密钥。

请勿使用与新生成的密钥相同的密码短语、名称、用户详细信息在新计算机上重新创建密钥,因为新生成的密钥将具有新的唯一ID,如果源使用先前生成的公钥进行加密,则仍会出现“无秘密密钥”错误。所以,需要导出和导入密钥来确保解密和加密使用相同的密钥ID。

gpg --output gpg_pub_key --export <Email address>
gpg --output gpg_sec_key --export-secret-keys <Email address>
gpg --output gpg_sec_sub_key --export-secret-subkeys <Email address>

gpg --import gpg_pub_key
gpg --import gpg_sec_key
gpg --import gpg_sec_sub_key

如果必须重新安装操作系统并从头开始创建具有相同名称、用户详细信息等的新密钥,会发生什么? - basickarl

2

这种情况发生在我身上,解决方案取决于导致问题的原因。在我的情况下,我删除了初始化密码数据库的密钥,因此解决方案是删除我的主目录中的.password_store文件夹。如果您以同样的方式造成了此问题并且没有存储密码,请尝试这个方法。


1
我已解决了这个问题,尝试使用root权限,例如sudo gpg... 我认为没有权限提升的gpg不涉及文件权限,而是系统权限。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接