最后需要向maven官方仓库推送一个新包,但是却发现以前的 GPG 密钥找不到了。。这将直接导致maven在接纳新包时进行 GPG 验证签名失效,这时候应该怎么办呢?
GPG
首先需要简单了解下GPG。简单来说 GPG 是非对称加密算法 RSA 的实现。它能够根据私钥、公钥机制进行数据的加密、解密;同时也可以根据私钥、公钥的机制进行签名。
加解密与签名、验签
在信息安全的课程中,我们更多的学习的是 RSA 的加密与解密方法,简单来讲,加密就是把把原文中所有的信息进行处理,然后得到对应的密名,明文(补齐后)与密名的长度是相等的。
而签名并不对明文进行加密,他的作用只是判断明文是否被篡改。其实现原理如下:
- 对明文进行哈希处理,得到其哈希值
- 对哈希值使用私钥进行加密,得到的结果即是签名
所以验证的逻辑如下:
- 对明文进行哈希处理,得到其哈希值
- 对签名使用公钥进行解密
- 匹配1,2的结果,一致则说明明文未被篡改,验签成功
GPG验签
当maven的官方仓库接收到我们上传的jar时,会使用GPG进行验签,而验签则需要该签名对应的公钥。此时maven官方仓库则会向 GPG 的公钥服务器中根据签名的用户ID
去请求公钥,然后根据请求到的公钥对 JAR 包进行验签。
所以想验签成功需要以下几个因素:
- 在发布(上传)jar时,需要上传jar包对应的签名信息
- GPG 公钥服务器中必须存在签名用户 ID 对应的公钥
- GPG 公钥服务器中的公钥需要与本地的私钥是一对
如果未满足上述3个条件,则会报如下错误:
- 未获取到签名信息
- 未找到对应的公钥
- 验签失败
GPG 公钥服务器
GPG 公钥服务器其实是一组服务器,这些服务器间互通有无,从而达到了共享 GPG 公钥的目的,所以我们只要向这组服务器中的一个推送公钥就可以了。其它的服务器会在一定的范围内进行数据的共享,从而达到在任意一个公钥服务器上去获取公钥都可以成功的目的。
公钥服务器:
keyserver.ubuntu.com
subkeys.pgp.net
重置GPG 密钥
所以如果GPG的私钥丢失了,解决的办法则是:重新生成一个GPG 密钥对,然后把公钥重新上传到 GPG 密钥服务器。接着使用这个新的 GPG 私钥对文件进行签名就可以了。
安装GPG
gnupg是一款开源的 GPG 软件,可以快速的帮助我们生成、管理 GPG 密钥对。
下载方式:
# Debian / Ubuntu 环境
sudo apt-get install gnupg
# Fedora 环境
yum install gnupg
# macos
brew install ngupg
创建密钥对
使用命令 gpg --gen-key
创建一个密钥对,输入完用户名及邮箱地址后,会出现确认信息:
Real name: name
Email address: email@qq.com
You selected this USER-ID:
"name <email@qq.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
这个 name <email@qq.com>
即是当前密钥的用户id
。此时输入O来确认,接收会弹出让我们输入一个保护此私钥的密码,以避免有人在未授权的情况下使用私钥。
接收我们使用一鼠标、键盘的一些操作来随机的生成密钥对,最后密钥对便产生了:
pub rsa3072 2023-12-31 [SC] [expires: 2025-12-30]
F28358C2AAA021B831BAD7B559C086C400FC8E2F
uid name <email@qq.com>
sub rsa3072 2023-12-31 [E] [expires: 2025-12-30]
此时这个 F28358C2AAA021B831BAD7B559C086C400FC8E2F
即是密钥 ID
。
上传密钥对
即可以使用用户id
进行上传,也可以使用密钥id
进行上传,比如:
gpg --keyserver keyserver.ubuntu.com --send-keys F28358C2AAA021B831BAD7B559C086C400FC8E2F
总结
新的公钥被上传至公钥服务器后,便可以在发布jar包时使用私钥对jar包进行签名了,然后maven服务器在接收到jar包后,会由公钥服务器上下载公钥,从而成功的进行验签。
GPG是RSA的一种实现,在 MAVEN 包管理中,它起到的验签的作用,从而避免了 JAR 包在发布的过程中被篡改的情况。
参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。