最近有需要在 Github 上配置 SSH 和 GPG,因此,将过程记录下来形成本文。没啥技术含量,就是一个记录。我这里使用的主机环境是 Ubuntu 22.04 LTS 和 Windows 22H2 build 22621。

  无论是 SSH 还是 GPG,都是对于密码学(编码学)的应用。更进一步,它俩都使用了非对称加密方式。我对于加密也不是很懂,下面列出一些常见概念:

  • 对称加密:在加密和解密时使用的是同一个秘钥
  • 非对称加密:加密算法需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)
  • CA:Certificate Authority,证书授权中心 / 电子认证服务机构,受公众信任足够权威的第三方机构,负责管理和签发证书的。
  • CA 证书 = 数字证书:经过 CA 认证的证书,包含 签证机关的信息证书拥有者信息证书拥有者的公钥权威机构的签字有效期 等信息
  • 指纹 = 摘要 = 哈希值 = 杂凑值
  • 密钥能力 = 密钥用途

SSH

  SSH 为 Secure Shell 的缩写(虽然名字中有个 Shell,但他实际并不是 Shell),由互联网工程任务组(Internet Engineering Task Force,IETF)的网络小组(Network Working Group)所制定一个网络协议。

  SSH 的经典用途是登录到远程电脑中执行命令。除此之外,SSH 也支持隧道协议、端口映射和 X11 连接。借助 SFTP 或 SCP 协议,SSH 还可以传输文件。

SSH 的详细介绍具体参考:Network 之六 SSH、SSL、OpenSSH、OpenSSL、LibreSSL

  SSH 只是一种协议,存在多种实现,既有商业实现,也有开源实现。目前,OpenSSH 是最流行的 SSH 的开源实现,而且成为了大量操作系统的默认组件。SSH2 通常指 SSH Communications Security, Inc. (http://www.ssh.com) 实现的 SSH 协议版本 2 的专有软件名字。

安装

  目前,SSH 已经成为了类 Unix 系统的标配组件,直接在 Ubuntu 终端中输入 ssh -V 就可以查看 Ubuntu 自带了 ssh 客户端的版本;同样,从 Windows 10 1803 版本开始,微软也提供 OpenSSH 工具,直接在 Windows Terminal 中(CMD)输入 ssh -V 就可以查看当前系统中的 SSH 版本。
在这里插入图片描述
  默然情况下,Ubuntu 和 Windows 都没有了提供 SSH 的服务端。如果需要服务端,需要自行进行安装。Ubuntu:sudo apt-get install openssh-server;Windows:设置 → 应用 →可选功能 → openssh-server,具体参考:Network 之六 SSH、SSL、OpenSSH、OpenSSL、LibreSSL

生成 KEY

  生成 KEY 的过程在 Ubuntu 和 Linux 上并没有区别。需要注意的是,SSH 支持的加密算法有好几种,根据需要选择一个合适的即可。此外,Github 推荐 ssh-keygen -t ed25519 -C "your_email@example.com",但是在一些旧系统并不支持 ed25519 这个算法。我这里选择使用 RSA 算法。
在这里插入图片描述
  生成的 KEY 的存放位置一般默认,直接回车即可(如果要生成多个 KEY 的话,这里就可以指定不同的名字来区分了)。至于密码,看个人需要,可以选择直接回车,从而不设置密码。然后,SSH 就会列出我们生成的 KEY 文件了。

  Linux 系统内置有 Keyring机制,可以方便查看我们的 SSH 密钥。一般桌面都有对应的 GUI 程序,KDE 上有 KDE 钱包,GNOME 和其他桌面上叫做密码和密钥
在这里插入图片描述

Keyring 参考:https://zhuanlan.zhihu.com/p/128133025?from_voters_page=true

部署 GITHUB 及 GITEE

  经过上面生成 KEY 之后,在我们指定的目录下就会有 id_rsaid_rsa.pub 这两个文本文件。其中,id_rsa 是私钥,需要我们保存好,id_rsa.pub 是公钥,把公钥内容添加到 GITHUB 及 GITEE 即可。
在这里插入图片描述

注意,在将 KEY 添加到 GITHUB 或 GITEE 时,需要验证我们对应的 GITHUB 或 GITEE 的账户密码。

使用及效果

  配置好我们生成的 SSH 公钥之后,就可以选择使用对应仓库的 SSH 方式访问仓库了。需要注意,第一次 SSH 连接,会有类似的提示:“The authenticity of host ‘github.com (20.205.243.166)’ can’t be established.xxxxxxx.This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])?”。这里选择 yes 即可。
在这里插入图片描述
  每次本地 Commit 代码并推送到 Github 仓库或 Gitee 仓库后,在 SSH 的配置页面上都会显示我们最近有没有使用它。
在这里插入图片描述

GPG

  GPG 又称 GnuPG,全称 GNU Privacy Guard,是一个遵照 OpenPGP 协议的用于加密、数字签名以及认证的软件。它是 PGP(Pretty Good Privacy)的开源实现,PGP 则是 Symantec 公司的专有软件。

GPG 的详细介绍具体参考:使用 GPG Key 来构建签名、加密及认证体系简明 GPG 概念

  在数字世界,我们经常需要进行邮件加密、数字签名或者登陆认证等操作,GPG 就是这样一个既可以方便我们管理公私钥,又可以随时满足我们需求的密钥管理工具。GPG 的用途要比 SSH 登录密钥丰富得多。

简写能力(Capability)/用途(Usage)说明
[C]Certificating认证其他秘钥、给其他秘钥签名。类似于 SSL/TLS 根证书
[S]Signing签名。例如,给文件添加数字签名,邮件签名,git commit 签名
[A]Authenticating身份验证、鉴权,例如,SSH 登陆
[E]Encrypting加密。例如,消息加密,文件加密

  一个 GPG 密钥对之所以可以有这么多能力,是因为它本质上是若干密钥对的集合,只不过它们被封装到了一起。所有子密钥的有效性,都来自于主密钥的认证。子密钥可以在没有主密钥的情况下单独使用。
在这里插入图片描述

  • 主私钥必须有 认证 [C] 这个能力,且这项能力只能属于主私钥。
  • 主私钥可以同时拥有 认证 [C]、签名 [S]、身份验证 [A] 三项能力。
  • 子私钥可以同时拥有 签名 [S]、身份验证 [A] 两项能力。
  • GPG 的建议创建一个拥有 加密 [E] 能力的独立子私钥。
  • 如果子密钥被泄露的话,可以只吊销子密钥。子密钥可以单独使用,但是,无论是那种用途,它都是由主键签名并同时传输的。这种做法允许自行撤销子密钥,同时保持主密钥有效。

  从图中可以看出来,整个“密钥串”只有一张吊销证书,一旦这张证书发布,主密钥即被吊销,连带着子密钥一并吊销。那子密钥丢失了怎么办呢?GPG 不允许用户生成子密钥的吊销证书,而是把变更都放在唯一的公钥中,简洁且不易出错。你只需要编辑“大”密钥,将子密钥单独吊销,然后重新发布公钥即可,这样大家就都知道了。

  实际上子密钥的公钥是存在的,也可以导出,但 GPG 为了防止用户误用,把这项功能藏得很深。毕竟,如果子密钥的公钥也单独使用,那就跟自己设计一个证书信任链没什么区别了。我们在实际使用中,导出的“公钥”实际上是一组公钥,其中就包括了被主私钥【认证 [C]】后的各个子公钥。

  与 TLS 基于集中式的信任链不同,GPG 并不搞集中式,虽然开源世界中有不少 GPG 公共服务器组成的【公钥服务器池】(Web of Trust),但 GPG 将信任与否的决定权交给用户。OpenPGP 提供的开放的公钥服务器池地址是 https://keys.openpgp.org/,用户可以自由上传自己的公钥,方便他人知悉。世界上有两种密钥信任体系:

  1. GPG:相信你所相信的人(Web of Trust)。 简单来说,就是大家都把自己的公钥放到一个互联网上(例如,GPG 提供的 https://keys.openpgp.org/),好让别人都知道自己。这样在双方通信的时候,只要使用对方的公钥验证信息通过就可以确认对方身份。
  2. TLS:相信权威(CA)。 CA 的根证书一般都已内置于操作系或浏览器中,根证书是无条件信任的。因为信任根证书,因此,也要信任根证书认证的其他证书。

安装

  对于大多数 Linux 系统发行版,默认都提供了在线安装选项,例如 Ubuntu:sudo apt-get install gnupg,选择在线安装是最简单的;对于其他系统,GnuPG 官网提供了多个平台的预编译二进制文件,下载地址是 https://www.gnupg.org/download/。
在这里插入图片描述
  对于 Windows 用户,可以选择 GUI,我比较喜欢命令行的简洁 ,选择了安装纯命令行。注意,最的版本是 2.x,不要选择旧版,因为他们的参数互相不兼容。安装好之后,直接使用命令 gpg --version 即可查看对应的版本。
在这里插入图片描述

Windows 系统上 GUI 版,网友写了详细的过程 https://blog.csdn.net/u011174139/article/details/120139497

生成 KEY

  生成 KEY 的过程在 Ubuntu 和 Linux 上并没有区别。需要注意的是,GPG 支持的加密算法有很多,但是,GITHUB 及 GITEE 并不是全部都支持。Github 支持 RSA、ElGamal、DSA、ECDH、ECDSA、EdDSA;Gitee 没找到官方说明。我这里选择使用 RSA(GitHub 推荐使用 4096 位及以上的以 RSA 协议的 KEY),直接输入命令 gpg --full-generate-key,然后回车,其他步骤见下图。
在这里插入图片描述
  其中,第五步需要注意,这里有可能是弹出 GUI 的对话框,让输入一个密码(第二次输入用于确认密码),来保护我们上面填写的用户身份(UID,包含全名(一般是实名)、邮箱地址(用 < > 包括)、注释(用 ( ) 包括),例如,上图中的ZCShou (zcs) <72115@163.com>),界面如下
在这里插入图片描述

  • 一个密钥可以有多个 UID,方便不同场合使用。
  • UID 与哪个子密钥无关,UID 是作用于整个密钥的。
  • UID 可以随时添加,但已有的 UID 不能修改,只能单独吊销。
  • UID 单独吊销后,只需要重新发布公钥即可

  Linux 系统内置有 Keyring 机制,可以方便查看我们的 GPG 密钥。一般桌面都有对应的 GUI 程序,KDE 上有 KDE 钱包,GNOME 和其他桌面上叫做密码和密钥
在这里插入图片描述

Keyring 参考:https://zhuanlan.zhihu.com/p/128133025?from_voters_page=true

部署 GITHUB 及 GITEE

  1. 查看私钥。使用命令 gpg --list-secret-keys --keyid-format=long 可以列出我们之前创建的秘钥 ID(图中红色框中的部分)。其中,sec 和 ssb分别是主密钥和子密钥(我们使用 gpg --full-generate-key 命令默认就是创建一个主密钥和一个子密钥)
    在这里插入图片描述

    • KEY 指纹 是公钥的散列值(默认使用 MD5 算法),gpg 中的 fingerprint 与 SSH 的计算方法略有不同,SSH 中 fingerprint 是直接对 base64 的结果再计算 MD5 得来,而 gpg 则对合并后的 modulus 和 exponent 的二进制进行 MD5 计算而来。
    • GPG 中使用 fingerprint 来作为 KEY-ID,用来标识一个 Key。Long ID 用 fingerprint 的后 16 位字符来表示,Short ID 则用 fringerprint 的后 8 位字符来表示。

    主密钥和子密钥都是独立生成的,两者在生成时彼此之间并无依赖关系;但是在生成之后,GPG 用一个叫 Binding Signature 的东西把两种进行关联。简单来说就是主密钥对子密钥进行签名,声明自己对子密钥的 Owner 关系;同时子密钥也对主密钥进行签名,声明自己对主密钥的 Member 或 slave 关系。RFC 4880 中对此有解释如下:
    在这里插入图片描述

  2. 查看公钥的具体内容。公钥由私钥导出,使用命令 gpg --armor --export 上面的私钥 ID 就可以导出公钥。
    在这里插入图片描述
    直接使用 gpg --list-keys 就可以查看公钥的基本信息。其中,pub 和 sub 分别是主公钥和子公钥
    在这里插入图片描述

    注意,如果有多个 GPG 密钥,则会显示多组

  3. 将以上公钥(-----BEGIN PGP PUBLIC KEY BLOCK----------END PGP PUBLIC KEY BLOCK----- 以及它俩之间的 KEY 内容)内容添加到 Github 和 Gitee 上去。添加方式非常简单,在他们的个人账户设置界面中,有专门添加 KEY 的地方。在这里插入图片描述

注意,在将 KEY 添加到 GITHUB 或 GITEE 时,需要验证我们对应的 GITHUB 或 GITEE 的账户密码。

配置 GIT

  1. 配置 Git 使用公钥检查提交签名。全局配置命令:git config --global user.signingkey GPG-KEY-ID,其中,GPG-KEY-ID 就是 gpg --list-secret-keys --keyid-format=long 列出的 KEY 的名字。
    在这里插入图片描述

  2. 开启自动签名。全局配置命令:git config --global commit.gpgsign true,针对单个仓库命令(要在仓库目录下执行):git config commit.gpgsign true。如果这里不配置,在使用 git commit 时,需要使用 -S 参数指定签名。

  3. 在 Windows 上需要显示指定 GPG 程序。全局配置命令:git config --global gpg.program "C:\Program Files (x86)\gnupg\bin\gpg.exe"。如果这里不配置,Commit 代码时会报错:gpg: skipped "xxxxx": No secret key。注意将以上命令中换为自己的安装路径。

使用及效果

  正常配置好上面的 GIT 之后,每次我们在本地 Commit 代码,GIT 都会自动调用 GPG 来给我的 Commit 进行签名,我们完全感觉不出有与之前有和变化。可以使用 git log --show-signature -1 来查看签名

  当我们正常在 GITHUB 及 GITEE 部署好 KEY 并且配置好 GIT 之后,每次本地 Commit 代码并推送到 Github 仓库或 Gitee 仓库后,对应的 Commit (在 GITHUB 或 GITEE 的 Commit 列表查看)就会显示一个验证标签。
在这里插入图片描述

gpg: can’t connect to the agent: IPC connect call failed

  今天在提交代码时,提示 gpg: can’t connect to the agent: IPC connect call failed。这个是由于 gpg-agent 没有正常启动导致的。根据 官网说明,当我们用到 gpg 时,gpg-agent 会自动启动,但是我这里却没有,不知道为啥。解决方法也很简单,手动启动一下 gpg-agent 即可:gpg-agent --daemon --verbose
在这里插入图片描述

SSH 对比 GPG

  • SSH(Secure Shell) 用于交互通信过程中的安全,是双向的。
  • GPG(GNU Privacy Guard) 既可用于加密,也可用于签名,这些都是单向的。
  • 私钥在 SSH 中被称为 private key,而在 GPG 中被称为 secret key。公钥则都叫 public key。
  • 一般来讲,SSH 的公钥只有你的服务器知道,别人也不需要知道。GPG 的公钥则巴不得全世界知道,告诉大家“认准这个证书,谨防假冒!”
  • 对于 SSH,建议一站一钥,万一丢了也好处理。对于 GPG,一把主钥+多个子钥即可。完全可以把 GPG 的子密钥 [A] 用于 SSH 登录。

参考

  1. https://blog.csdn.net/u011174139/article/details/120139497
  2. https://zhuanlan.zhihu.com/p/481900853
  3. https://zhuanlan.zhihu.com/p/137801979
  4. https://docs.github.com/cn/authentication/managing-commit-signature-verification/generating-a-new-gpg-key
  5. https://www.codercto.com/a/49711.html
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐