如何修复GPG错误"NO_PUBKEY"?

我用软件源程序添加了一些额外的存储库。但是当我重新加载软件包数据库时,会出现以下错误:
W: GPG 错误:http://ppa.launchpad.net trusty InRelease:由于公钥不可用,无法验证以下签名:NO_PUBKEY 8BAF9A6F
根据官方的Ubuntu文档,我知道可以使用终端中的apt-key来修复它。但我希望能够以图形方式完成。有没有不使用终端的方法来解决这个问题?

1相关链接:http://askubuntu.com/q/127326/178596 - Wilf
“一点意思”?好奇你指的是什么。 - Michael Scheper
1你可以查看这个SO thread来找到解决方案。还可以点击相关网站的链接。 - Aniket Thakur
@MichaelScheper '有没有不用打开终端的方法?' = '有没有一种不需要使用终端的方式?' - Wilf
@Wilf:哦!我不是要挑剔语法,但确实让我有些困惑。从我刚查阅的参考资料来看,“means”是一个单数名词,而且这正是你所指的意思。但是,如果你和Agmentor使用的是某种变体英语,其中问题的语法是正确的,我很愿意看到相关的参考资料,因为我对这类事情很感兴趣。☺ - Michael Scheper
对于想要删除存储库的用户,请参见此问题(这应该使这个评论更加相关,尽管我认为在这里评估语法也很重要 :))@MichaelScheper 这是一种不寻常的说法,但作为英国英语的一部分,我已经学会了(这可能意味着我的英语比如果我受到正确教育(有名词等)!xD)。引用“a means to end”(一种结束的手段)这句话浮现在脑海中,虽然那里的问题在于结尾,但这就是means表示方法或方式的地方。 - Wilf
@Wilf:我提供的词典是一本英国词典,“a means to an end”完全说明了我的观点,即“means”是单数形式。因此,“mean”不是正确的词。但你说得对,我们已经偏离了主题,所以我将退出进一步讨论,并由你决定是否编辑问题。谢谢。 - Michael Scheper
这里有一个可靠的答案:https://askubuntu.com/a/15272/481928 - Greenish
14个回答

在终端中执行以下命令。
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <PUBKEY>

在这里,<PUBKEY> 是您缺失的存储库的公钥,例如 8BAF9A6F

然后进行更新。

sudo apt-get update

备用方法:

sudo gpg --keyserver pgpkeys.mit.edu --recv-key  <PUBKEY>
sudo gpg -a --export <PUBKEY> | sudo apt-key add -
sudo apt-get update

请注意,当您使用apt-key导入此类密钥时,您正在告诉系统您信任要导入的密钥以签署您的系统将使用的软件。除非您确信该密钥确实是软件包分发者的密钥,否则请不要这样做。

1这个命令怎么反转啊,它产生了很多Ign并且没有起作用。看这个链接:http://img688.imageshack.us/img688/6885/igny.png - Black Block
2@Naruto 这很正常。它意味着服务器上的那个列表没有发生变化。 - nanofarad
15你可以将NO_PUBKEY值直接传递给keys参数。例如GPG错误[...]NO_PUBKEY 3766223989993A70 => sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3766223989993A70 - S.M.Mousavi
348BAF9A6F 我从您之前的问题中看到了这个数字。 - Olivier Lalonde
18原始错误中显示的是8BAF9...这个数字。它类似于NO_PUBKEY 8BAF...。 - Alex
13如果有人在我和代码库之间篡改了数据,并替换了他们签名的内容,那么我只会盲目地添加他们使用的密钥。那么,如何验证这个密钥是否正确呢? - mc0e
2最终,您是在信任密钥服务器(例如,在第一个示例中为keyserver.ubuntu.com)。 - Phil_1984_
2这是一个很好的答案。只需注意,提问者特别要求以图形方式完成,而不是使用命令行。 - monotasker
2@monotasker:确实。要是我先看到这个答案就好了,因为我更喜欢打字,而不是每天都在图形界面中翻来覆去。但公平地说,楼主最后确实要求了一个图形化的方法。 - Michael Scheper
对于备用方法,实际上你不需要指定密钥服务器,因为gpg有一个它信任的服务器池。 - jpaugh
2@Phil_1984_,@jpaugh:不,使用PGP时,密钥服务器从不被信任。密钥通常通过UID的签名链或手动检查来进行验证,例如比较密钥ID或指纹。后者实际上是您使用apt-key --recv-key 3766223989993A70时所做的操作:您告诉apt-key您信任具有该密钥ID的密钥。如果密钥服务器尝试返回一个不同的密钥,apt-key将不会接受它来替代3766223989993A70 - cjs
Ubuntu 16.04服务器的最佳解决方案。 - Ariful Haque
在最近的Debian Stretch上,我首先需要安装dirmngr软件包。 - mvw
1尽管OP要求以图形方式,但我需要用CLI,并且这解决了我的问题。 - dylanh724
这在Ubuntu 16上仍然可行! - Bernhard Döbler
密钥添加适用于 Debian 10。我不得不添加几个公钥。 - Timo
72022年8月28日在Jammy上的声明: 警告:apt-key已被弃用。请改为在trusted.gpg.d中管理密钥环文件(参见apt-key(8))。 - s.k
2这两种方法都对我没用。我成功添加了密钥,但当我再次运行sudo apt-get update时,仍然出现相同的错误。 - Thomas Levesque
我确认在Ubuntu 22.04中无法正常工作... - Ricky Robinson

目前处理这个问题最简单的方法是使用Y-PPA-Manager(它现在将launchpad-getkeys脚本与图形界面集成在一起)。
要安装它,首先添加webupd8存储库以获取此程序:
sudo add-apt-repository ppa:webupd8team/y-ppa-manager 更新软件列表并安装Y-PPA-Manager:
sudo apt-get update sudo apt-get install y-ppa-manager 运行y-ppa-manager(即输入y-ppa-manager然后按回车键)。
当主要的y-ppa-manager窗口出现时,点击“高级”。
从高级任务列表中选择“尝试导入所有缺失的GPG密钥”,然后点击确定。
完成!正如警告对话框在开始操作时所说,这可能需要相当长的时间(对我来说大约2分钟),具体取决于您有多少个PPA和您的连接速度。

请注意,在添加仓库时,它会输出链接webupd8.org/2010/11/y-ppa-manager-easily-search-add-remove.html以获取更多信息。 - Elijah Lynn
42在Web服务器上并不是非常有用,因为它会安装X11。如果你使用的是服务器版,请不要使用这种方法,可以查看karthick87的回答! - goncalotomas
执行sudo apt-get update时出现错误:W: GPG错误:http://ppa.launchpad.net trusty InRelease:无法验证以下签名,因为公钥不可用:NO_PUBKEY 089EBE08314DF160 - Mitch
2这可以验证导入的密钥,还是您只是盲目地导入所有内容(因此信任拥有PPA的每个人)? - Paŭlo Ebermann
3你正在导入(并信任)你系统中添加的每个PPA的密钥。假设你信任这些PPA,并在通过apt添加它们之前对它们进行了检查。 - monotasker
1有没有人知道y-ppa-manager在“高级>尝试导入所有丢失的GPG密钥”中使用的命令是什么?这真的非常有帮助,我很想将其设置为别名,这样就不必启动y-ppa-manager了,如果只需要这样做的话。谢谢! :) - Ev-
7这个答案比那个“图形化”的答案要简单得多,实际上需要的命令也更少。 - jpaugh
2但是问题要求使用图形方法。 - monotasker
y-ppa-manager 在我的 Ubuntu 17.10 上无法“打开显示器”。 - Mobigital
这在大多数服务器上是行不通的,你之前提到过这个应用程序需要GUI才能运行,我浪费了15分钟来安装它。下面的答案中的命令是完美的:apt-key adv --keyserver keyserver.ubuntu.com --recv-keys <PUBKEY> - Salem F
1您会注意到问题中明确指定了“是否有不使用终端的方法来完成这个任务?” - monotasker
如果你有多个丢失的钥匙,那就不是这样了。 - vikki
@vikki 实际上,批处理作业是命令行的一大优势。你可以像这样执行:for pubkey in Key1 Key2 Key3 ... KeyN; do sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$pubkey"; done。在这种情况下,key1...KeyN 是一个以空格分隔的公钥 ID 列表,应该被导入。(不应包括点本身。)如果你需要导入更多的密钥,这个方法将更加方便,因为你可以让它运行并离开,直到完成为止。 - jpaugh
@jpaugh 拿到钥匙是我认为艰巨的任务。有没有一个命令可以列出缺失的钥匙? - vikki
不,我没有。这将取决于你为什么需要它们。(或者也许是你怎样弄丢了它们?)我从未一次添加过多个ppa,并且想不到需要密钥的其他原因。 - jpaugh
错误:检索GPG密钥超时。 - Giorgi Gvimradze
你的修复方法是使用apt-get update,但这样做是行不通的,因为缺少密钥,这毫无意义。 - Shardj
不要安装这个,错误:8 http://ppa.launchpad.net/webupd8team/y-ppa-manager/ubuntu groovy Release 404 Not Found。 - Seandex

当你没有适合的公钥用于一个仓库时,就会出现这个问题。
要解决这个问题,请使用以下命令:
gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 9BDB3D89CE49EC21

从Ubuntu密钥服务器检索密钥。然后是这样的:
gpg --export --armor 9BDB3D89CE49EC21 | sudo apt-key add -

这将添加apt可信密钥的关键。

解决方案可以在这里这里这里找到。


5如果 hkp://keyserver.ubuntu.com 无法使用,请使用 pgpkeys.mit.edu 服务器。 - RajaRaviVarma
2这个回答解决了我在麒麟软件源上的问题。搜狗拼音输入法添加了源到我的/etc/apt/sources.list.d/文件夹,但显然没有导入gpg密钥。好答案,简洁明了,加一! - Sergiy Kolodyazhnyy
1谢谢!对我来说解决了php仓库问题。 - Akash Agarwal
1这个答案解决了我的更新问题,http://ppa.launchpad.net/webupd8team/java/ubuntu xenial InRelease - mvw
很有可能,你之前没有为你的系统生成密钥。因此,在按照上述步骤之前,请使用gpg --gen-key命令生成密钥(参考链接:http://packaging.ubuntu.com/html/getting-set-up.html)。 - parasrish
这太棒了,简单而精确。 - Danny Sofftie
2警告:apt-key已被弃用 - Daniel Andrzejewski

你需要获取并导入密钥。
要从PPA获取密钥,请访问PPA的Launchpad页面。在每个PPA页面上,您会在“关于此PPA的技术细节”(1)后找到这个链接(2)。

image 1

跟着它,点击密钥ID链接(3):

image 2

保存这个页面,这是你的关键文件。

现在是导入的时候:

  • 应用程序 > 软件中心
  • 编辑 > 软件源...
  • 输入您的密码,
  • 转到认证选项卡,然后点击导入密钥文件...,最后
  • 选择保存的密钥文件,然后点击确定

1不要浪费时间,看下面的答案。 - Felipe
5@FelipeMicaroniLalli,问题是如何使用图形界面添加公钥,而不是终端,所以这个答案非常完美。 - Chris Woods
现在使用y-ppa-manager(也是一个图形界面应用程序)来做这个事情要容易得多、快得多。请参阅下面的回答。 - monotasker
1好的,但是如果存储库不是Ubuntu PPA怎么办?例如,Intel在https://download.01.org上运行他们自己的视频硬件驱动程序存储库。 - mc0e
非常棒的逐步指南,非常感谢!对于那些无法通过apt-key添加密钥的人来说真的很有帮助。 - Roy Ling

注意:根据最近的版本,将PPA密钥添加到密钥环中不再被视为良好的做法。但是,我将保留这个答案,但apt-key现在已被弃用,建议我们现在遵循其他方法

apt只能处理/etc/apt/trusted.gpg.d中的40个密钥。如果有41个密钥,即使您按照所有步骤添加缺失的密钥,也会出现GPG错误“找不到公钥”。

检查一下该文件中是否有来自不再使用的ppa的未使用的密钥。如果全部都在使用中,请考虑删除一些ppa以及/etc/apt/trusted.gpg.d中相应的密钥文件。

此外,使用

sudo apt-key adv
被认为是安全风险,不建议使用,因为您正在"破坏整个安全概念,这不是一种安全的密钥接收方式,有很多原因(例如:hkp是明文协议,短的甚至长的密钥ID都可以伪造,...)"。http://ubuntuforums.org/showthread.php?t=2195579

我相信正确的添加丢失的密钥(例如1ABC2D34EF56GH78)的方法是

gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 1ABC2D34EF56GH78
gpg --export --armor 1ABC2D34EF56GH78 | sudo apt-key add -

1我发现直接删除/etc/apt/trusted.gpg.d下的所有密钥,然后按照这个回答http://askubuntu.com/a/386003/284664进行操作更容易。 - janot
@mchid 你能否提供一个关于这个41键限制的文件/网址的引用? - SebMa
@SebMa 链接已发布在我的答案中,并引用了受到此限制影响的Debian中的一个错误。这是链接中实际帖子的锚点,其中提到了这一点:https://ubuntuforums.org/showthread.php?t=2195579#post_message_12882784 我不确定是否存在关于此的实际文档,但数字40可能被用来表示“许多”在许多不同语言中。 - mchid
@SebMa 不过,在回答时,限制是存在的,而且在此之后的一段时间内也是如此。我个人经历过这个41个键的限制,并通过删除未使用的键来添加新键,以避免出现此错误。 - mchid
此外,这并不意味着如果您有少于41个键就不会遇到此错误。当您缺少某个键时,同样会出现此错误。因此,首先检查一下是否有太多的键,然后通过正确添加键来解决问题。 - mchid
@SebMa 如果你想要更多信息,只需在谷歌上搜索:“gpg邮件列表“40-keys””,结果中有很多相关引用。 - mchid
@mchid 谢谢。还有一件事,你在回答中说不要使用 sudo apt-key adv,因为 hkp 是一个明文协议,那么你的 gpg --keyserver ... 命令为什么包含了这个 hkp URL:hkp://keyserver.ubuntu.com:80,它不也是一个明文 URL 吗? - SebMa
@SebMa 我没有说过那个。明文的事情只是在帖子中提到的其中一件事。我使用的备用命令来自Debian的文档。 - mchid
@mchid 抱歉,我没有注意到这是来自Debian文档。你知道一种更安全的方法来添加丢失的密钥吗? - SebMa
1@SebMa 不,https://wiki.debian.org/SecureApt - mchid
3警告:apt-key已被弃用 - Daniel Andrzejewski
2@DanielAndrzejewski 是的,谢谢。我稍后会更新答案。在此期间,您可以按照这些说明来作为另一种向存储库添加密钥的方法。另外,如果您使用了这种其他方法,请记得从密钥环中删除相应的密钥,这样密钥只适用于单个存储库。它被弃用的原因是将密钥添加到密钥环中会将密钥应用于所有存储库。将密钥添加到您的sources.list文件中的单个存储库只会应用于该单个存储库。 - mchid
@DanielAndrzejewski 或者,如果它是一个PPA,你可以简单地删除/etc/apt/sources.list.d/目录中与该PPA对应的源列表文件,然后使用sudo add-apt-repository命令再次添加该PPA。再次添加PPA应该会自动更新密钥到最新版本。唯一的问题是,这种方法似乎容易受到相同的安全漏洞的影响(它将密钥添加到全局密钥环中)。 - mchid
1@mchid 我的问题与docker-ce和containerd.io软件包有关。 Docker-ce是最新版本,但containerd.io软件包被锁定在某个版本上,与最新的docker-ce不完全兼容。当我删除了版本锁定并更新了containerd.io软件包后,问题得到解决。 - Daniel Andrzejewski
@DanielAndrzejewski 这是很好的。顺便说一下,似乎我们应该能够使用 apt-key 添加密钥,然后将密钥简单地移动到 /etc/apt/keyrings,以避免安全问题,然后手动将该路径链接到源列表文件中每个仓库的密钥文件。尽管如此,我还没有测试过这个方法。 - mchid

在WebUpd8 PPA中有一个小脚本,我将以单个.deb下载的方式提供链接,这样您就不必添加整个PPA了-它会自动导入所有缺失的GPG密钥。

下载并安装Launchpad-getkeys(忽略版本中的~natty,它适用于从Karmic到Oneiric的所有Ubuntu版本)。安装完成后,打开终端并输入:

sudo launchpad-getkeys

如果你在使用代理服务器,情况会变得更加复杂一些,请参考this获取更多信息。

1确实,这是我现在所使用的方法,因为我在你们的网站上看到了这个程序的介绍。然而,我的问题的目的是想知道如何以图形化的方式来完成。 - Agmenor
launchpad-getkeys脚本现已集成到Y-PPA-manager程序中。https://launchpad.net/~webupd8team/+archive/y-ppa-manager - monotasker

我在安装Heroku时遇到了同样的问题。以下链接解决了我的问题 -

http://naveenubuntu.blogspot.in/2011/08/fixing-gpg-keys-in-ubuntu.html

修复了NO_PUBKEY问题后,以下问题仍然存在。
W: GPG error: xhttp://toolbelt.heroku.com ./ Release: The following signatures were invalid: BADSIG C927EBE00F1B0520 Heroku Release Engineering <release@heroku.com>

为了修复它,我在终端中执行了以下命令:
sudo -i  
apt-get clean  
cd /var/lib/apt  
mv lists lists.old  
mkdir -p lists/partial  
apt-get clean  
apt-get update  

来源 - 解决方法链接


我仍然遇到相同的错误,GPG 错误:http://download.opensuse.org/repositories/home:/colomboem/xUbuntu_16.04 Release: 下列签名无效: - Itamar Katz

确保你已安装 apt-transport-https
dpkg -s apt-transport-https > /dev/null || bash -c "sudo apt-get update; 
sudo apt-get install apt-transport-https -y" 

添加仓库:
curl https://repo.skype.com/data/SKYPE-GPG-KEY | sudo apt-key add - 
echo "deb [arch=amd64] https://repo.skype.com/deb stable main" | sudo tee /etc/apt/sources.list.d/skype-stable.list 

安装Skype for Linux。
sudo apt-get update 
sudo apt-get install skypeforlinux -y

来源: https://community.skype.com/t5/Linux/Skype-for-Linux-Beta-signatures-couldn-t-be-verified-because-the/td-p/4645756

此错误也可能发生在 PPA 的 apt 列表文件指向本地的密钥环时。

deb [signed-by=/usr/share/keyrings/SOMETHING.gpg] https://download.something.org/something something/

虽然该文件可能存在于您的系统上(可能是通过先前的命令下载的),但由于缺少权限,它可能无法读取。我刚刚通过运行以下命令来修复这种错误:
chmod 644 /usr/share/keyrings/*

在获取钥匙环文件之后,出现了一个潜在的问题,就是在我已经是root用户的情况下使用sudo命令。真的很奇怪,因为所有这些都是以root身份运行的,而且没有任何访问权限失败的消息...但是这样做解决了问题。

1这也是为什么它对我不起作用的原因。Hashicorp提供的GPG密钥指示在我的Ubuntu上不起作用,因为权限设置不正确。经过chmod之后,apt终于能够读取文件了。 - Jodiug
我遇到了一个类似的问题,keyrings目录的权限设置不正确。我通过运行sudo chmod 755 /etc/apt/keyrings来修复它。 - undefined

更一般地说,以下方法适用于每个存储库。首先,在需要的情况下,借助搜索引擎的帮助,在程序提供商的网站上搜索类似以下的文本:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.1 (GNU/Linux)
[...]
-----END PGP PUBLIC KEY BLOCK-----

例如,这样的文本在http://deb.opera.com上显示。将段落复制后,粘贴到你在桌面上创建的空文件中。这将生成密钥文件。

然后继续导入密钥:

  • 应用程序 > 软件中心
  • 编辑 > 软件源......,输入密码
  • 点击“认证”选项卡,选择“导入密钥文件...”
  • 选择保存的密钥文件,然后点击“确定”。

现在可以删除之前创建的密钥文件。