UP | HOME

GPG

目录

概念

“主”(认证)密钥

  1. 在“主密钥”和“子密钥”之间没有技术上的区别。
  2. 在创建时,我们赋予每个密钥特定的能力来分配功能限制。
  3. 一个 PGP 密钥有四项能力
    1. [S] 密钥可以用于签名
    2. [E] 密钥可以用于加密
    3. [A] 密钥可以用于身份认证
    4. [C] 密钥可以用于认证其他密钥
  4. 一个密钥可能有多种能力

带有 [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. 备份所有密钥,删除当前机器上的主密钥

           # 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. 做好导出的私钥的备份,删除不需要的文件。
    
  2. 备份所有密钥到加密的移动介质,删除主密钥,在移动介质中使用 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 已安全备份。删除上述文件夹。
    
  3. 使用 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>
    

gpg-agent

Links

作者: Petrus.Z

Created: 2021-09-01 Wed 00:38