哪些命令(确切地)可以替代已弃用的apt-key?

在一个新的Ubuntu 20.10虚拟机上为本地仓库设置密钥时,我收到了一个消息,说apt-key add已经被弃用了,我应该阅读apt-key(8)手册页。apt-key(8)手册页是一串词语的集合,但如果它包含了我无法理解的信息。有人可以告诉我,在终端上,我应该输入什么来替代原来的命令吗?
apt-key add name-of-file

这个命令在我按喇叭后似乎还是起作用了,所以我能继续前进,但我想知道将来需要做什么。
8个回答

你需要知道为什么`apt-key add`已经被弃用。
到目前为止,所有的答案都解决了症状("不要使用`apt-key add`"),但未能解决导致`apt-key add`被弃用的实际问题。这个问题不是将一个密钥追加到一个大的密钥环文件`etc/apt/trusted.gpg`还是手动将单个密钥环文件放入目录`/etc/apt/trusted.gpg.d/`的问题。这两个方法是等效的,而且无论哪种方式都会带来巨大的安全风险。
问题在于你添加到上述任何一个地方的密钥都是完全可信任的,这意味着当从任何存储库(包括官方发行版存储库)安装任何软件包时,apt都会欣然接受由这些受信任的密钥之一签名的软件包(无论该密钥是否属于软件包所来自的存储库)。这削弱了软件包签名机制对恶意软件包注入官方Ubuntu镜像网络的保证。
我们想要做的是配置apt只接受来自第三方软件源的签名,仅限于从该软件源安装的软件包,不进行交叉签名。Apt的默认优先级规则将官方发行版软件源放在更高的位置,这样(结合适当的密钥管理)可以一定程度上防止第三方软件源替换发行版提供的软件包。(至少我认为是默认设置。您可以使用apt-cache policy命令检查当前的优先级设置,并根据origin调整优先级以实现此效果。有关详细信息,请参阅man apt_preferences。)
Ugo Delle Donne在他的回答中给出了将密钥转换为apt接受的(传统的)密钥环v4格式的正确和有用的说明,但这只是解决方案的一部分。我在这里重申一下(稍作整理),以便所有步骤都集中在一个地方:
下载密钥: ``` wget https://host.domain.tld/path/to/. ``` (不需要使用`-O`或`>`;`wget`默认将文件保存在当前目录,并以服务器上的相同文件名命名。)
验证文件类型是否为“PGP公钥块公钥(旧)”: ``` file . ```
`gpg`支持多种密钥格式,如果您的密钥是其他格式的,请先将其导入到临时密钥环中,然后再导出它: ``` gpg --no-default-keyring --keyring ./temp-keyring.gpg --import . gpg --no-default-keyring --keyring ./temp-keyring.gpg --export --output .gpg rm temp-keyring.gpg ```
现在你已经有了转换后的密钥,请不要将其添加到apt的信任密钥库中,通过将其复制到/etc/apt/trusted.gpg.d/。相反,将其放在像/etc/apt/keyrings/这样的地方。(你可能需要首先创建那个keyrings目录。)这个位置没有什么特别之处,它只是Ubuntu 22.04中man 5 sources.list和相关的Debian Wiki条目推荐的约定。
在这一点上,没有什么改变,apt也不知道这个密钥的存在。最后一步是修改该存储库的特定.list文件,告诉apt在哪里找到该特定存储库的密钥。
  • 编辑文件/etc/apt/sources.list.d/<example>.list,在deb和URL之间添加[signed-by=/etc/apt/keyrings/<your-keyfile-name>.gpg]
现在apt将接受该密钥在该软件源中的所有软件包的签名,仅限于该软件源。 备注:
  • 如果您已经在/etc/apt/trusted.gpg.d/目录下有密钥环文件,您可以将它们原封不动地移动/etc/apt/keyrings/目录中,然后更新所有相应的.list文件,使每个文件都有一个指向自己密钥的signed-by字段。
  • 如果您在/etc/apt/trusted.gpg密钥环文件中除了官方仓库密钥之外还有其他密钥,this answer详细介绍了定位和删除这些密钥的步骤。然后,您可以按照上述相同的步骤以更安全的方式设置它们。(也可以从该密钥环中导出它们,但具体步骤留给读者自行探索。)
  • 要将存储库的密钥从密钥服务器导入到独立文件中:
    • gpg --no-default-keyring --keyring <output-file-name>.gpg --keyserver <some.keyserver.uri> --recv-keys <fingerprint>
    • 这样可以获得一个apt可以接受而无需转换的密钥。
  • Apt仍然非常信任,恶意或被入侵的存储库可以轻易绕过此措施,因为当前软件包可以在其设置脚本中以root身份运行任意shell代码。尽管关闭一个攻击向量并不会有害,但在其他方面也正在(缓慢地)取得进展。
  • 可选地,您可以切换到使用单独的.sources文件而不是.list文件的较新、更详细的Deb822格式。这需要更多工作,但我个人认为结果更易读。

参考资料:


无需导入/导出密钥进行转换。您可以使用wget -O - https://host.domain.tld/path/to/<keyfile>.<ext> | gpg --dearmor > /usr/local/share/keyrings/<your-keyfile-name>.gpg一步解除密钥的装甲。 - Hrobky
3@Hrobky 是的,如果密钥是一个已经转换为ASCII码的旧二进制格式的“公钥块”,那么它可以工作。然而,如果密钥文件是以较新的二进制“密钥库数据库”格式存储的,而apt不支持该格式,那么需要将其实际转换为旧的公钥块格式(在适用的情况下解码)。如果存在一步完成二进制→二进制转换的命令,我还没有遇到过。 - Askeli
1好答案。@Askeli能否给出一个直接使用gpg --dearmor可行的密钥的例子,以及一个不可行的例子? 例如,我是否正确地认为这个mopidy密钥可以与--dearmor一起使用,但这个google密钥不能?请注意,将google密钥直接传递给gpg --dearmor仍然以错误代码0退出,这说明...它能正常工作吗? - laur
就我所知,根据@Hrobky的建议通过gpg --dearmor进行处理,我还没有遇到任何无法使用的密钥。 - laur
2@laur 对不起,我没有例子。当我写这个回答的时候,我下载、转换和安装了一堆密钥,我相信在此期间至少遇到了一个即使经过 --dearmor 后 apt 仍无法识别的密钥,这促使我去寻找我的回答中的转换方法……但是我没有记录下具体哪些密钥。一般来说,默认情况下通过 --dearmor 进行处理不会有任何问题(如果密钥不是 ascii-armored 的话,gpg 会顺利退出而不做任何更改)。如果 apt 在处理后的密钥上出现问题,那么再尝试进行二进制到二进制的转换解决方法。 - Askeli
13这意味着任何第三方仓库,只要其apt签名密钥存在其中,就可以替换您整个系统上的任何软件包,无需任何问题。即使您使用了较新的方法,这也是可能的,对吗?因为apt仍然无法区分哪个仓库被允许提供哪些软件包。除非您还实施了一些固定策略,但我在任何说明中都没有看到这一点。 - Robie Basak
1@laur 一个(ASCII)装甲的PGP密钥只是非装甲的PGP密钥文件的base64编码版本,其中包含一些头部/尾部文本以指示它是一个PGP密钥。这样做是为了使数据可以通过仅接受/期望ASCII文本而不是任意二进制数据的方法轻松发送。惯例是对此类文件使用“.asc”扩展名,对于二进制密钥文件使用“.gpg”。Mopidy显然没有遵循这个惯例。似乎“file”命令对于装甲文件总是报告“PGP公钥块公钥(旧)”,对于非装甲文件则提供更详细的信息。 - Jivan Pal
1@laur 当有疑问时,用文本编辑器打开文件(例如 less my-file.ext,按 Q 键退出),如果文件经过加密,则会有可读的标头,如“BEGIN PGP PUBLIC KEY BLOCK”。如果是二进制文件,在打开前 less 将告诉你它是二进制文件,因为试图显示其内容将呈现乱码/乱码化 - Jivan Pal
5有没有什么原因,为什么这个过程不是通过一些apt命令自动替换已弃用的行为呢?根据描述,似乎可以很容易地编写脚本来实现。 - Snackoverflow
1在Ubuntu 21.04上,我在/etc/apt/trusted.gpg.d/目录中有Ubuntu密钥,例如ubuntu-keyring-2012-cdimage.gpgubuntu-keyring-2018-archive.gpg。而且这些密钥没有相应的.list文件。所以我猜测不能盲目地移动该目录中的所有内容。 - Snackoverflow
它能防止第三方仓库替换系统中的任何软件包吗?如果可以,具体是如何实现的? - Alexandr Zarubkin
1我认为ppa现在也会成为一个问题?add-apt-repository ppa:user/ppa-name将会在/etc/apt/sources.list.d中添加一个文件,同时也会在/etc/apt/trusted.gpg.d中添加相应的密钥。PPA是否应该得到同样的对待呢? - Dodgyrabbit
你可以将这个答案与这个答案结合起来,以导出默认信任密钥环中的现有密钥,并将它们移动到你的本地目录中(即使在Debian上,一些密钥将位于/etc/apt/sources.list.d,而另一些则位于/etc/apt/trusted.gpg)。你还可以提到,在arch=amd64之后可以加上signed-by,用一个空格隔开。这可能看起来很明显,但有些人(包括我)可能希望得到确认 - 这样才能完整回答问题!除此之外,非常好的答案! - Rik
4@RobieBasak看起来Debian确实有这方面的说明,但我必须说,这听起来真的很复杂。希望add-apt-repository会得到更新,或者还会有其他工具能够自动化这个过程... - Compholio
4根据Ubuntu 22.04上的"man 5 sources.list",如果您是一个系统管理员想要添加带有密钥环的apt源,那么密钥环应该放在/etc/apt/keyrings/目录下(例如winehq仓库)。另一方面,如果您是一个软件包维护者,想要在软件包的postinst脚本中安装密钥环(例如google-chrome、Microsoft teams、slack),则应将其放置在/usr/share/keyrings/目录下。 - zeehio
1试想一下,你只有10秒的时间来传达你说的话,然后对方只有1分钟的时间来执行,否则我们都会灭亡。这就是安全应该看起来的样子。而不是一个庞大的系统,容易出现错误和漏洞。 - mathtick
嗯,除非变得简单一些,否则我不会做任何这样的事情,因为即使LLVM仍然使用apt-key。我更有可能通过sed将apt的输出导入并剥离警告,而不是为每个密钥都进行这样的操作。 - Chase
1谢谢。这是整个网络上唯一一个真正概述了如何正确处理最新apt签名存储库的答案。其他任何内容都与此毫不相关。对于简单的答案,将您的存储库密钥放在逻辑位置(例如/usr/share/keyrings),并直接在/etc/apt/sources.list或sources.list.d行中引用它。就这么简单。只需直接指向正确的密钥即可。 - trisweb
2你完全没有理解重点!问问自己:你推荐的东西是否符合Ubuntu的存在目的? …不,绝对不符合。正确的方式是,你选择的软件包管理工具应该询问用户:“你是否愿意完全无条件地信任$packageSourcePeople?将你的计算机交给他们?” …而且,在安装Ubuntu时,它也必须提出这个问题!因为你表现得好像Ubuntu的维护者们是以某种神奇的方式无法被腐败的,与其他人不同。这显然是极其危险的错误观点。 - anon
1此外,当没有办法/命令从ppa URI中确定密钥时,要求人们以神奇的方式手动找到该该死的密钥,实在是侮辱人。你可以直接说:“我们是博格^W苹果!放弃你自己的自由意志!抵抗是徒劳的!服从!服从!IÄ!IÄ!CANONICAL FHTAGN!” - anon
此外,apt-add-repository 仍然使用 apt-key add!这才是整个问题的根源所在!而你甚至没有提到它,一句话都没有。 - anon
2如果deb和URL之间已经有另一个条目,例如[arch=amd64],则您必须将其放在括号内,例如deb [arch=amd64 signed-by=/etc/apt/keyrings/vivaldi-release.gpg] http://repo.vivaldi.com/stable/deb/ stable main,否则apt会报语法错误:列表文件中的第3个条目格式不正确 - Ingo Steinke
2请将@IngoSteinke的建议添加到您的回答中(如果已经有括号内的条目,如何添加signed-by)。此外,这个工作流程中最让人讨厌的部分是找到每个源的gpg密钥,因为它们的存储方式没有一致的方法。最后,我只能将所有密钥从系统中移除,然后迭代运行apt-key update并通过搜索解决每个问题源以找到其密钥。我很惊讶这里有多少古老的密钥,将它们移除可能是个好主意... - undefined

我遇到了同样的问题,幸运的是其他问题为我指明了方向。 在我的例子中,我试图将TeamViewer存储库添加到最新的Kali Linux上,但是密钥验证一直阻止着我。
我相信有更优雅的方法来解决这个问题,但以下步骤帮助我解决了这个问题:
  1. 下载相关密钥

    wget -O - https://download.teamviewer.com/download/linux/signature/TeamViewer2017.asc > ~/teamviewer.key

  2. 验证文件类型

    file ~/teamviewer.key

    应该是PGP公钥块 公钥(旧)

  3. 创建一个密钥环

    gpg --no-default-keyring --keyring ./teamviewer_keyring.gpg --import teamviewer.key

  4. 这个文件仍然不是一个可以添加到/etc/apt/trusted.gpg.d/的有效密钥,因为它是一个密钥环,但是我们可以从密钥环中提取密钥

    gpg --no-default-keyring --keyring ./teamviewer_keyring.gpg --export > ./teamviewer.gpg

  5. 这个文件是您要移动到受信任密钥文件夹的密钥

    sudo mv ./teamviewer.gpg /etc/apt/trusted.gpg.d/

开心的 sudo apt update!!!


17不要使用这个被接受的答案,也不要将文件放在/etc/apt/trusted.gpg.d/目录下。请查看得票最多的答案,以获得更好的解决方案。 - Amedee Van Gasse

这个废弃的原因是因为使用apt-key add只是将gpg密钥附加到受信任的全局APT密钥环中。这类似于添加local_repo.list/etc/apt/sources.list.d/而不是使用add-apt-repository dep/link/to/repo version的首选方法,后者会将消息附加到全局sources.list文件中。
我认为这比使用.d文件夹更难理解,但本质上我们想要将gpg密钥放入一个独立的密钥环文件中,然后在源列表中指向该密钥环文件。默认的密钥环文件位置是/usr/share/keyrings,它可以是.asc或.gpg文件。我不确定区别,但我知道全局密钥环文件是二进制文件,不是纯文本文件。
例如:
有时使用通用名称可能有点难以理解,因此这里有一个安装mongoDB的示例:
获取MongoDB gpg密钥并将其添加到新的密钥环文件中。
curl https://www.mongodb.org/static/pgp/server-4.2.asc | sudo tee -a /usr/share/keyrings/buster-mongodb-org-4_2.asc

为apt添加一个源条目,指向这个新的密钥环。

例如,如果您的存储库文件位于/etc/apt/sources.list.d/mongodb-org-4_2.list,运行以下命令添加密钥文件:

echo "deb [signed-by=/usr/share/keyrings/buster-mongodb-org-4_2.asc] https://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4_2.list

从这个新添加的仓库安装mongodb
sudo apt install -y mongodb-org
参考资料
这对我来说还是比较新的,但我所知道的大部分都来自于unix SE中这个优秀答案的链接

我很好奇远程服务器上的文件server-4.2.asc是如何变成本地端的buster-mongodb-org-4_2.asc。那个文件名有重要的意义吗? - fIwJlxSzApHEZIl
需要注意的是,较新版本的MongoDB在Ubuntu上可能还需要[ arch=amd64,arm64 ]。我还不确定如何添加这个以及密钥路径的分隔符。 - mchid
1@mchid 选项之间的分隔符是一个空格,像这样: [arch=amd64,arm64 signed-by=...] - Moshe Katz

我创建了一个shell脚本,可以下载并安装用于[signed-by=]声明在sources.list中使用的密钥。
它可以在github.com/ameinild/add-apt-key上找到。

安装 APT 密钥的 POSIX 脚本

常规帮助

此脚本将帮助您安装 APT 存储库的 PGP 密钥。

此脚本支持最多 2 个参数:

  • 第一个参数是输入文件。可以是以下任一选项:
    • URL - 密钥将被下载到当前路径(使用 wget 或 curl)
    • 文件名 - 读取当前路径中的现有密钥
    • 路径和文件名 - 从给定路径中读取现有密钥
  • 第二个参数是密钥输出路径和输出名称。可以是以下任一选项:
    • 仅文件名 - 输出路径在配置中设置,保存为给定的文件名
    • 路径和文件名 - 在此处给出输出路径,保存为给定的文件名
    • 仅路径(以 / 结尾)- 在此处给出输出路径,文件名来自现有密钥
    • 空 - 输出路径在配置中设置,文件名来自现有密钥

此脚本有一个配置文件 /usr/local/etc/add-apt-key.conf,其中可以设置以下变量:

  • keypath :存储转换后密钥的路径 - 默认为 /etc/apt/keyrings
  • verbosity :如果设置为 Yes - 显示额外输出
  • removetmp :如果设置为 Yes - 删除输入(未转换)文件

示例 1:(PWD=/root

sudo add-apt-key https://mariadb.org/mariadb_release_signing_key.asc /usr/share/keyrings/

将在 /root 下载密钥,进行转换并保存为 /usr/share/keyrings/mariadb_release_signing_key.gpg

示例 2:(PWD=/home/user

sudo add-apt-key /root/mariadb_release_signing_key.asc /usr/share/keyrings/mariadbkey

将使用 /root 中的现有密钥,进行转换并保存为 /usr/share/keyrings/mariadbkey.gpg

示例 3:(PWD=/home/user

sudo add-apt-key mariadb_release_signing_key.asc mariadbkey

将使用 /home/user 中的现有密钥,进行转换并保存为 /etc/apt/keyrings/mariadbkey.gpg

安装 PGP 密钥后,还可以将密钥和存储库添加到 /etc/apt/sources.list

  • 在脚本中将作为第一个输入选项提供添加的选择
  • 如果选择是 Yes,则必须将存储库字符串粘贴为第二个输入选项

通过将相应的存储库行添加到 /etc/apt/sources.list 来完成密钥安装

安装

通过运行以下命令进行安装:

sudo curl -L https://raw.githubusercontent.com/ameinild/add-apt-key/master/add-apt-key -o /usr/local/bin/add-apt-key
sudo curl -L https://raw.githubusercontent.com/ameinild/add-apt-key/master/add-apt-key.conf -o /usr/local/etc/add-apt-key.conf
sudo chmod a+rx /usr/local/bin/add-apt-key

8因此,上面清楚地表明了Linux绝对不适合普通用户。那些Ubuntu及其他发行版应该警告用户,你需要具备严肃的高级技能,并且必须愿意花费大量时间进行培训、搜索和处理各种问题...更重要的是,几乎没有保证你所做的一切都会起作用或不会引发更多问题。这就是不诚实。 - Yann Monnier
3我非常确信未来的Ubuntu版本将会适应“新”的PGP密钥安装方式,并编写自己的脚本。与此同时,我已经编写了一个脚本,以帮助其他用户尽可能地自动化这个过程。如果你觉得它太高级或者没有用处,那也没关系,它实际上是为了提供帮助而存在的。 - Artur Meinild
1脚本已更新,添加了直接将GPG密钥和软件源写入到"/etc/apt/sources.list"的选项。 - Artur Meinild
2@YannMonnier 你完全正确。如果Ubuntu的开发人员不能将他们的“安全顾虑”与社区实际需求相匹配,那么Ubuntu桌面将不再是一个可行的选择。我是Slackware的忠实粉丝,那里的工具更加简洁高效(尽管缺乏文档)。它们可能也“不够安全”,但我们这里又不是银行 - 这只是一台个人电脑! - levitopher
3新的密钥默认位置是/etc/apt/keyrings - Artur Meinild
1@levitopher,相比Ubuntu的10万个软件包,Slackware只有约2000个软件包可用,它如何成为一个可行的选择呢?而我们现在正在讨论如何添加PPA以轻松扩展软件包数量,超过10万个。 - mchid
@mchid:权衡之处在于较少的预打包软件,但拥有更加功能强大和稳定的操作系统。在安装了前2000个软件包后,可靠性会大大降低。再加上这些apt密钥的麻烦事……你总是可以从源代码编译,这只是一种关于“便利”与“质量”调整的态度——Slackware注重质量,Ubuntu注重便利。我上面的观点实际上是关于Ubuntu“易于使用”的幻觉。在市场的一个小片段中,这是真实的,但对于许多人来说,这只是一个谎言。 - levitopher
1@mchid我的脚本直接引用了每个仓库的密钥。 - Artur Meinild
我喜欢这个评论区自己就在争论,而且没有我的指导,就为了证明Slackware比Ubuntu更好(甚至不需要...只要“可行”就行!)。过时的方法?很好的长期规划。多个链接提供多个深度的理解?并不完全符合KISS原则。密钥服务器相对于“网站”需要额外步骤?拜托,Google别让我失望!Slackware可能只是因为它是一个较小的项目才可行,但仍然专注于可靠性和长期规划,避免了大部分无意义的讨论。 - levitopher
@mchid:我觉得你没有理解KISS的要点(或者至少,我在这里提出的解释适用)。它不是“盲目地按下一个按钮然后进入太空 - 简单”。而是“使每个按下的按钮都能轻松理解和修复以进入太空 - 简单”。我认为Ubuntu构建的软件交付系统结构更像是黑匣子的例子 - 使用起来很简单,但一旦出现故障,需要完全不同的技能来使其重新运行。而在Slackware上,安装和修复所需的技能是相同的。 - levitopher
感谢@ArturMeinild编写这个脚本。看起来非常有用,但同时也表明Linux对于普通用户来说过于复杂,不适合作为一个正常的操作系统使用。我们只是想安装一个应用程序,这本不应该需要技术技能,却需要像你这样的操作系统专家编写脚本和冗长的解释,以便程序员和系统管理员能够弄清楚如何安装一个应用程序。 - Andrew Koster
请查看我的答案,从中获取apt-manage,我认为这是继续前进的方式。 - Lockszmith
@Lockszmith 但是它会移植到Ubuntu吗?目前看起来似乎只适用于Pop_OS! - Artur Meinild
我已经编辑了我的回答以提高清晰度,在Ubuntu上的安装(我在Ubuntu 20.04及其后续版本上进行)非常简单,结果是一个“干净”的系统。 - Lockszmith

作为直接的替代,将apt-key add替换为gpg --dearmorcurl [KEYURL] | sudo gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/[KEYFILE].gpg 然而,这并不推荐使用(除非作为apt-key的替代),因为受信任目录中的所有密钥都是无条件信任的;最好将输出放在一个(非全局)可信任的目录中(正如其他人建议的那样),并让每个源指定要信任的密钥。

更新:2023年5月16日,我可以确认apt-manage是我发现的最安全、最一致的管理apt源和密钥的方法。
我已经重写了答案,删除了我的个人脚本(如果你愿意,可以在修订历史中查看),专注于命令而不是我的个人代码。

这里的所有答案都很棒,我从中学到了很多。

根据 @mesterlion 的评论,截至目前为止,有一个工具可以完成所有这些任务,并且正确地进行维护 - 这个工具是由 Pop!_OS 团队开发的。

这个工具就是 apt-manage,它是 RepoLib 模块的一部分,在版本 2 中引入了 key 子命令。

所以在 Pop!_OS 22.04 中,安装过程将如下所示:

sudo apt install --yes apt-manage

上游项目(Ubuntu和Debian)缺少这个软件包,对我来说,以下命令可以在Ubuntu上成功安装它:
cd ~ # recommended
sudo apt update \
    && sudo apt install --yes python3-gnupg python3-debian \
    && curl -LO https://github.com/pop-os/repolib/releases/download/2.0.0/python3-repolib_2.0.0_all.deb \
    && sudo apt install ./python3-repolib_2.0.0_all.deb \
    && apt-manage --help

对于Debian来说,有构建说明 - 在git-repo的README.md安装部分

示例1

这是我系统中一组apt-manage调用的示例:

# Adding PPA
sudo apt-manage add --terse --format=sources ppa:ppa:alessandro-strada/ppa

# Adding APT source and assinging a key
sudo apt-manage add --terse --format=sources --name Microsoft --identifier packages-microsoft-com 'deb [arch=amd64] https://packages.microsoft.com/ubuntu/22.04/prod jammy main'
# Assigning a key via URL
sudo apt-manage key packages-microsoft-com --url=https://packages.microsoft.com/keys/microsoft.asc

# R-Project needed some additional love - because they do something 'different':
sudo apt-manage add --terse --format=sources --name R-Project --identifier cloud-r-project-org 'deb [arch=amd64] https://cloud.r-project.org/bin/linux/ubuntu jammy-cran40/ ""_""'
# Specific to R-Project, as one of the values are empty and the command line can' pass it effectively.
sudo sed -i /etc/apt/sources.list.d/cloud-r-project-org.sources -Ee 's/""_""//g'
# Assigning a key via fingerprint
sudo apt-manage key cloud-r-project-org --fingerprint=E298A3A825C0D65DFD57CBB651716619E084DAB9

# After all were added, run update.
sudo apt update

示例2:在全新的Ubuntu计算实例上初始化Docker

set -e
export DEBIAN_FRONTEND=noninteractive

apt-get update \
&& apt-get install --yes --no-install-recommends \
    apt-transport-https ca-certificates \
    wget gnupg software-properties-common lsb-release \
    curl jq bash-completion

has() { command -v "$1" > /dev/null; }

# Try differnt ways of installing apt-manage
# First let's hope there is package ready for installation
has apt-manage || apt-get install --yes apt-manage || true

# If it still doesn't exist, let's get it from repo
if ! has apt-manage; then
    FILENAME=python3-repolib_2.0.0_all.deb
    URL="https://github.com/pop-os/repolib/releases/download/2.0.0/$FILENAME"
    if [ ! -e "/tmp/$FILENAME" ]; then
        apt-get install --yes python3-gnupg python3-debian
        curl -Lo "/tmp/$FILENAME" "$URL"
    fi
    apt-get install "/tmp/$FILENAME"
fi

apt-manage add --identifier download-docker-com-pqb --name Docker \
    --terse --format=sources \
    "$( printf "deb [arch=%s] %s %s %s" \
        "$(dpkg --print-architecture)" \
        "https://download.docker.com/linux/ubuntu" \
        "$(lsb_release --codename --short)" \
        "stable"
    )"

apt-manage key download-docker-com-pqb \
    --url=https://download.docker.com/linux/ubuntu/gpg

1如果你使用PopOS,你可以直接使用apt-manage(来自repolib - MestreLion
不知道apt-manage这个命令。看起来这个命令只是替换了sudo tee这一行,用于写入.list文件,但是下载密钥的curl和验证密钥的gpg仍然是必需的。无论如何,这是工具箱中的另一个工具。谢谢@MestreLion! - Lockszmith
1apt-manage确实有选项可以从URL下载GPG密钥并将其与存储库关联起来。默认情况下,它使用/etc/apt/keyrings目录,这也是Debian推荐的方式。 - MestreLion
@MestreLion,你是对的,我编辑了我的回答以反映这一点,但后来发现这目前只在Pop!_OS上可用。 - Lockszmith
1它可以在Debian和Ubuntu上使用,并且在22.04版本中运行良好。只需从他们的GitHub发布页面获取.deb文件,或者按照首页README中的说明自己创建一个:https://github.com/pop-os/repolib - MestreLion
1在Ubuntu上安装的另一种方法是将PopOS存储库添加到apt中:add-apt-repository "deb https://apt.pop-os.org/release $(lsb_release -cs) main"。这可能是最佳途径(自动更新),但请确保还创建一个apt“pin”,以便它只从该存储库中获取repolib软件包,而不是其他软件包!。请参阅https://wiki.debian.org/AptConfiguration#Prevent.2Fselective_installation_from_third-party_a_repository - MestreLion
我同意,但我觉得我们把它留在评论里。我记得这不难,但有些非常规问题可能会让你犯难。 - Lockszmith
这看起来很有趣。我得自己在虚拟机上测试一下,但至少看起来很有前途。 - Artur Meinild
1同意,真的不知道为什么它没有得到应有的喜爱。这是一个写得很好的工具。 - Lockszmith
已更新为官方快速安装脚本。 - undefined

如果你有*.asc文件,你可以直接使用--dearmor命令解密它。
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/

用于apt的密钥存储在/etc/apt/trusted.gpg.d/中。apt-key为您管理这些密钥环,但现在它已被弃用,您需要自己选择一个适当的文件名<KEYRING>来管理密钥环。

如果您已经有了作为本地文件的密钥<FILE>,请运行

gpg --no-default-keyring --keyring=gnupg-ring:/etc/apt/trusted.gpg.d/<KEYRING>.gpg --import <FILE>

直接从<URL>读取密钥,请运行
curl -sSfL <URL> | gpg --no-default-keyring --keyring=gnupg-ring:/etc/apt/trusted.gpg.d/<KEYRING>.gpg --import

注意:在密钥环名称之前需要添加前缀gnupg-ring:,以便创建与apt兼容(传统)v4格式的密钥环,而不是(较新的)keybox v1格式。

如果我想要添加 gpg key: EBB4CCF6A72BC110 | 55D9B3F8D3E163D4CED77D9CEBB4CCF6A72BC110 到这个 PPA:https://launchpad.net/~ufleisch/+archive/ubuntu/kid3,我应该如何修改你提到的命令呢?我尝试了:curl -sSfL https://keyserver.ubuntu.com/pks/lookup?fingerprint=on&op=index&search=0x55D9B3F8D3E163D4CED77D9CEBB4CCF6A72BC110 | gpg --no-default-keyring --keyring=gnupg-ring:/etc/apt/trusted.gpg.d/<KEYRING>.gpg --import,但是没有成功。 - Jags
(1)在这个PPA的情况下,应该是什么<URL>https://launchpad.net/~ufleisch/+archive/ubuntu/kid3?(2)我是否应该用gnupg-ring.gpg替换<KEYRING>.gpg?非常感谢。 - Jags
2@Jags curl -sSfL 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x55d9b3f8d3e163d4ced77d9cebb4ccf6a72bc110' | sudo gpg --no-default-keyring --keyring=gnupg-ring:/etc/apt/trusted.gpg.d/kid.gpg --import - kynan
非常感谢,还有一个问题请教。当我想要一次性导入多个密钥进行新安装时,我可以像这样添加更多的URL吗 curl -sSfL <URL> <URL> <URL>?谢谢。 - Jags
密钥已成功添加,但现在当我运行 sudo apt update 时,我遇到了很多错误,例如:W: http://ppa.launchpad.net/ufleisch/kid3/ubuntu/dists/hirsute/InRelease: The key(s) in the keyring /etc/apt/trusted.gpg.d/kid.gpg are ignored as the file is not readable by user '_apt' executing apt-key. 非常感谢。 - Jags
@Jags sudo chmod 0644 /etc/apt/trusted.gpg.d/kid.gpg - kynan
@Jags "我可以添加更多的URL吗?"不行。而且你可能想把它们放在不同的钥匙环上。 - kynan