GPG
概念
“主”(认证)密钥
- 在“主密钥”和“子密钥”之间没有技术上的区别。
- 在创建时,我们赋予每个密钥特定的能力来分配功能限制。
- 一个 PGP 密钥有四项能力
- [S] 密钥可以用于签名
- [E] 密钥可以用于加密
- [A] 密钥可以用于身份认证
- [C] 密钥可以用于认证其他密钥
- 一个密钥可能有多种能力
带有 [C] (认证)能力的密钥被认为是“主”密钥,因为它是唯一可以用来表明与其他密钥关系的密钥。只有 [C] 密钥可以被用于:
- 添加或撤销其他密钥(子密钥)的 S/E/A 能力
- 添加、更改或撤销密钥关联的身份(uid)
- 添加或更改本身或其他子密钥的到期时间
- 为了网络信任目的为其它密钥签名
在自由软件的世界里,[C] 密钥就是你的数字身份。一旦你创建该密钥,你应该格外小心地保护它并且防止它落入坏人的手中。
Command
常用命令
# 生成密钥 gpg --expert --full-gen-key # 编辑密钥,具体编辑操作可见Links 1,2 gpg --expert --edit-key <key/uid/email> # 显示公钥 gpg -k gpg --list-keys # 显示私钥 gpg -K gpg --list-secret-keys # 将key提交到keyserver gpg --keyserver hkps://hkps.pool.sks-keyservers.net --send-keys <keyid/uid> # 手动生成吊销证书 # 一般在生成密钥时会自动生成,保存在~/.gnupg/openpgp-revocs.d目录下 gpg --output revoke.asc --gen-revoke <keyid/uid> # 吊销密钥(导入吊销证书) gpg --import ~/.gnupg/openpgp-revocs.d/<keyid>.rev # 在keyserver中更新已吊销的key gpg --keyserver hkps://hkps.pool.sks-keyservers.net --send-keys <keyid/uid> # 在keyserver中查找公钥 gpg --keyserver hkps://hkps.pool.sks-keyservers.net --search-keys <keyid/uid> # 从keyserver导入公钥 gpg --keyserver hkps://hkps.pool.sks-keyservers.net --recv-keys <keyid/uid> # 导出公钥 # 导出为二进制文件: gpg --output yourname.gpg --export <keyid/uid> # 导出为文本文件: gpg --armor --output yourname.txt --export <keyid/uid>
添加 SSH keys
# 1. 导出authentication子密钥为ssh公钥 gpg --export-ssh-key <keyid> # 2. 将导出的ssh公钥复制到需要的地方 # 3. 输出authentication子密钥的keygrip gpg -k --with-keygrip # 4. 将输出的keygrip添加到~/.gnupg/sshcontrol中 # 5. 运行gpg-agent并使用ssh-add -L命令确认添加成功 # ssh-add -L输出的值与gpg --export-ssh-key命令的输出结果相同 ssh-add -L
导入他人公钥
# 先获取某人的公钥(从公钥服务器上): gpg --recv-keys <keyid/uid> # 或者指定一个 keyserver : gpg --keyserver hkps://hkps.pool.sks-keyservers.net --recv-keys <keyid/uid> # 或者从文件导入某人的公钥: gpg --import /tmp/file # 检查一下指纹: gpg --fingerprint <keyid/uid>
文件加密解密、签名与验签
# 1. GPG加密操作,由发送方进行,首先获取接收方公钥,使用公钥加密文件 gpg --output 加密输出文件 --recipient <uid> --encrypt 待加密文件 # --recipient参数后跟对方的用户ID;--output参数后面跟导出的文件名;--encrypt参数后跟要加密的文件。 这里应该注意一个问题,就是你要确定你使用的公钥的可靠性。 # 注意参数顺序,--encrypt 待加密文件在最后 # 将加密后的文件发送到接收方,在接收方解密 gpg --output 解密输出文件 --decrypt 加密后的文件 # 注意参数顺序,--decrypt 加密后的文件在最后 # 2. 文件签名操作由文件分发方来做,首先,分发方使用自己的密钥对文件签名, # 并将签名后的文件(或者文件与文件签名)分发出去。 # 接收者使用分发方的公钥对文件进行验签,证明文件没有被篡改。 gpg --sign xxxx.xxx # 这个命令会在当前目录下生成 xxxx.xxx.gpg,这是签名后的文件。采用二进制储存。 gpg --clear-sign xxxx.xxx # 这个命令会生成ASCII签名后的文件。文件名为xxxx.xxx.asc。签名被添加在文件头和文件尾。 # 以上两个命令都是将签名添加到文件中,一般都不会用。 gpg --detach-sign xxxx.xxx # 这个命令会在当前目录下生成 xxxx.xxx.sig 这是文件的签名。采用二进制储存。 gpg --detach-sign --armor xxxx.xxx # 这个命令会生成文件的ASCII签名xxxx.xxx.asc。 # 3. 验证签名 gpg --verify --output 输出文件 xxxx.xxx.gpg gpg --verify --output 输出文件 xxxx.xxx.asc gpg --verify xxxx.xxx.sig gpg --verify xxxx.xxx.asc # 上面四种验签方式对应四种签名方式。 # 4. extras # 指定用某个私钥签名: gpg -u YYYYYYYY --sign-key XXXXXXXX # 再要求询问签名的过期日期: gpg -u YYYYYYY --sign-key --ask-cert-expire XXXXXXXX # 再要求询问有效性: gpg -u YYYYYYY --sign-key --ask-cert-expire --ask-cert-level XXXXXXXX # 导出并发送给别人 gpg --armor --export XXXXXXXX | gpg --encrypt -r XXXXXXXX --armor --output XXXXXXXX-signedBy-YYYYYYYY.asc
密钥分离思想
该使用且只使用子密钥,主密钥应该放在一个绝对安全的地方。
无论加密还是签名都可以直接使用公钥,但我们并不推荐这样做,因为如果直接使用公钥,而密钥又不小心被泄露了,我们就不得不吊销整个密钥。
为了解决这一问题,我们应该使用且只使用子密钥,这样如果子密钥被泄露了,我们仅需要吊销被泄露的子密钥,这样主密钥仍是安全的,然后用主密钥生成新的子密钥继续使用。
备份所有密钥,删除当前机器上的主密钥
# 1. 导出密钥 # 导出所有密钥,作为备份: gpg --output all_secret_keys --export-secret-keys <keyid/uid> # 导出某个子密钥: gpg --output some_secret_subkeys --export-secret-subkeys <keyid>! # 可以单独导出,也可以一同导出,注意 ID 后的感叹号,此符号确保主密钥不会被同时导出,再例如: gpg --output some_secret_subkeys --export-secret-subkeys <keyid1>! <keyid2>! # 2. 删除密钥 # 删除私钥: gpg --delete-secret-keys <keyid/uid> # 删除公钥: gpg --delete-keys <keyid/uid> # 或者,将以上两条命令合为: gpg --delete-secret-and-public-key <keyid/uid> # 3. 重新导入子密钥: gpg --import some_secret_subkeys # 如此以来,实现了主、子密钥分离 # 4. 信任密钥: gpg --edit-key <keyid/uid> # 输入trust命令(过程略) # 5. 做好导出的私钥的备份,删除不需要的文件。
备份所有密钥到加密的移动介质,删除主密钥,在移动介质中使用 gpg
# 1. 备份home目录下的 .gnupg 到加密的移动介质上。 # 2. 删除主密钥 gpg --with-keygrip --list-key <keyid/uid> # 找到主密钥的 keygrip ,记住。在 ~/.gnupg/private-keys-v1.d 下删除对应的主密钥文件。 # 3. 可以指定在移动介质的环境里运行 gpg : gpg --homedir <dir> <some commands here> # 4. 备份并删除吊销证书 # 确保 ~/.gnupg/openpgp-revocs.d 已安全备份。删除上述文件夹。
使用 2 个 U 盘,导出密钥到 1 号 U 盘,导出子密钥到 2 号 U 盘,并将吊销证书导入到 1 号 U 盘。删除刚生成的密钥。
此时,1号 U 盘中有密钥和吊销证书,2号 U 盘中有子密钥。将 1 号 U 盘保存到一个*绝对安全的地方*。
在需要使用 GPG 的机器中插入 2 号 U 盘,导入到本地中并修改信任度,并将其公钥发送到 keyserver 上,这样就可以安全的仅使用子密钥。
# 1. 导出密钥到1号U盘 gpg -o /run/media/mogeko/USB1/gpg_key --export-secret-keys <keyid> # 2. 导出子密钥到2号U盘 gpg -o /run/media/mogeko/USB2/gpg_key.sub --export-secret-subkeys <keyid> # 3. 生成吊销证书并保存早1号U盘中(过程略) # 4. 删除刚生成的密钥 gpg --delete-secret-keys <keyid> # 5. 在本地导入2号U盘中的子密钥 gpg --import /run/media/mogeko/USB2/gpg_key.sub # 6. 修改该子密钥的信任度(过程额) # 7. 将公钥发送到keyserver中 gpg --keyserver hkps://hkps.pool.sks-keyservers.net --send-keys <keyid>