GnuPG 使用

开始使用
生成密钥
GnuPG 使用公钥来进行加密,使用私钥来解密。

gpg –gen-key
它用来生成你的密钥:流程如下:

[11:26:12] emacsist:~ $ gpg --gen-key
gpg (GnuPG) 2.0.30; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
# 使用哪种类型的密钥(默认的就够了)
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
# 密钥的长度
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
# 密钥有效期(默认为永不过期,默认的也够了)
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
# 以上信息是否正确
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.
# 你的真实名
Real name: emacsist
# 你的邮箱
Email address: emacsist@qq.com
# 备注
Comment:
You selected this USER-ID:
"emacsist "

# 是否要修改名字,备注,邮箱或OK、退出?
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

# 以上步骤完成后,就要输入保护私钥的密码了,这个也是整个GnuPG最脆弱的环节
密钥的废除
如果你忘记了私钥的保护密码或者丢失了私钥,你可以使用这个来发布通知,让其他人知道该公钥已经不再会使用:

gpg --output revoke.asc --gen-revoke emacsist@qq.com
这个要在确认你的密钥无效了的情况下才公布这个证书,在此之前,要确保其他人访问不了这个证书,否则其他人也可以发布这个证书然后让你的公钥失效。

交换密钥
导出公钥
为了发送你的公钥给其他人,首先你要导出它。

gpg --output emacsist.gpg --export emacsist@qq.com
默认情况下,导出的是二进制格式的。GnuPG 支持一个选项: –armor 它可以导出为 ASCII 格式。在任何导出的选项中,都可以使用这个选项来指定导出为 ASCII 格式。

列出公密钥
gpg --list-keys
导入公钥
gpg --import emacsist.gpg
删除某个公钥
gpg --delete-key emacsist@qq.com
验证公钥
一旦导入了一个公钥,就需要去进行验证它了

[11:56:22] emacsist:/tmp $ gpg --edit-key emacsist@qq.co
gpg (GnuPG) 2.0.30; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub 2048R/2E67BCA8 created: 2017-03-29 expires: never usage: SC
trust: ultimate validity: ultimate
sub 2048R/FCB22855 created: 2017-03-29 expires: never usage: E
[ultimate] (1). emacsist

gpg> fpr
pub 2048R/2E67BCA8 2017-03-29 emacsist
Primary key fingerprint: B698 23B4 571F 98EE CEDA 59C9 2B07 0A29 2E67 BCA8

gpg>
fpr 就会打印出该密钥的指纹,然后再通过拥有者的电话,或者email(或其他任何方式,只要你能保证他是该密钥的真实拥有者即可),然后让密钥拥有者将它的密钥指纹发给你,然后再进行二者对比,验证是否一致即可。

检测完密钥的指纹后,就可以进行签名认证它了。在上面后续命令中,输入 sign 即可。

导出私钥
gpg --output emacsist@qq.com.private.key --export-secret-keys emacsist@qq.com
导入私钥
gpg --allow-secret-key-import --import emacsist@qq.com.private.key
列出私钥
gpg --list-secret-keys
删除一个私钥:
gpg --delete-secret-key emacsist@qq.com
信任密钥
gpg -edit-key emacsist@qq.com
然后输入 trust 注意,此时要将相应的 gpg 进程退出后才能重新生效。不然,还会报 untrust 的警告。

加解密文档
加密文档
使用公钥来进行加密
gpg --output hello.txt.gpg --encrypt --recipient emacsist@qq.com hello.txt
–recipient 可以有多个同名选项来分别指定不同的公钥,加密后的文档,只能用这些公钥对应的私钥之一来进行解密。

多个公钥的话,可以这样子指定:

gpg --output hello.txt.gpg --encrypt --recipient emacsist@qqcom --recipient emacsist1@qq.com hello.txt
特别地,你自己并不能解密你加密后的文档,除非你将你自己的公钥与写在了 –recipient 列表中

使用对称密码来进行加密
gpg --output hello.symmetric.gpg.txt --symmetric hello.txt
回车后,它会要求你输入密码来保护这个文档,注意,这个密码,并不是那个保护私钥的密码,也不要与保护私钥的密码相同。这个在解密时,也需要输入同样的文档密码来进行解密。这一般用在不需要与其他人进行通信时使用的加密方式。

解密文档
解密使用公钥来进行加密的文档
gpg --output hello.decrypt.txt --decrypt hello.txt.gpg
解密使用对称密码来进行加密的文档
gpg --output hello.symmetric.txt --decrypt hello.symmetric.gpg.txt

[12:18:26] emacsist:/tmp $ cat hello.symmetric.txt
Hello World
数字签名
签名
它是使用私钥来创建,然后使用公钥来进行验证的。

gpg --output hello.txt.sign --sign hello.txt
验证或恢复原文
给出一个签名的文档,你可以验证它或者验证并恢复原文。(因为签名后的内容是压缩的,并且是二进制格式的)

仅验证
gpg --verify hello.txt.sign
验证和恢复
gpg --output hello.sig.txt --decrypt hello.txt.sign
签名但并不压缩文档
默认情况下,使用 –sign 会进行签名并压缩文档。 但也可以使用 –clearsign 选项,来将文档和签名分开显示。例如:

gpg --output hello.sign --clearsign hello.txt
它的输出如下:

[12:36:42] emacsist:/tmp $ cat hello.sign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hello World
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBCAAGBQJY3ItWAAoJECsHCikuZ7yo7rwH/1mfxVtxXexHsnKamR434Fjt
jjhIy27PajVecm7byyHLHrBCP/meDk4jl+wDDPpE8+0FJE17M8opW1YFZUzUXj52
bG+0kLZNtuIn2f3ybbsXGfcvmxo4n7B7jvDHJBqHDS8OMoc2nfUurN/XbYO10Mm3
YmBoEKjxk2Q6DHU3eJlnaOWXdPhZzCt24zjCrMdkG5iZln80TMHJyxXJD63zBzB1
dkHpX/vYgmy2EzDMZXBApatzSoys0/siGlZ64jnS8m61zlWPLhpMl3haSAPk5VDx
+ydw/c/9SO3cVjTzWLmXfW3hvvN/UW/HDOHb1j29yUhalztI1zTtEm2VyHiKJFo=
=LP7m
-----END PGP SIGNATURE-----
可以看到,上面显示了文档的原文,下面显示了文档的签名。

分开签名
gpg --output hello.detached.sign.txt --detach-sign hello.txt
这样子签名后,需要同时验证原文件和签名文件,用选项: –verify :

[12:40:37] emacsist:/tmp $ gpg --verify hello.detached.sign.txt hello.txt
gpg: Signature made Thu Mar 30 12:40:28 2017 CST using RSA key ID 2E67BCA8
gpg: Good signature from "emacsist " [ultimate]
没问题的话,它会报告: Good signature

概念
GnuPG 使用几种加密方式:

对称加密
使用同样的 key 来进行加解密,例子有: 3DES , Blowfish , 以及 IDEA
公钥加密
使用对称加密的问题并不在于它的安全性,而是在交换 key 。攻击者容易拦截 key 并破解它;另一个问题是如果有N个人需要通信,则就需要有 n(n-1)/2 个 key了。这在小范围通信还好,如果是与大量的人进行这样子的通信,就不是一个明智的选择了。 公钥加密就是用来避交换 key 的问题的。公钥用来进行加密,私钥来来进行解密。
(no term)
单向散列
杂交加密
公钥加密并不是万能的。它同时使用对称加密和公钥加密。
数字签名
一个哈希函数,是一个多对一映射的函数。一个文档的数字签名就是将一份文档应用到一个哈希函数得出的结果。这个函数要满足以下两个特性:

比较困难地将两份不同的文档产生出同一个值
给出一个哈希值,比较困难地还原该文档
密钥管理
篡改密钥是一个使用公钥方式的一个主要弱点。在GnuPG 中管理密钥的关键就是 签名密钥

比如:

chloe% gpg -edit-key chloe@cyb.org
Secret key is available.
pub 1024D/26B6AAE1 created: 1999-06-15 expires: never
sub 2048g/0CF8CB7A created: 1999-06-15 expires: never
sub 1792G/08224617 created: 1999-06-15 expires: 2002-06-14
sub 960D/B1F423E7 created: 1999-06-15 expires: 2002-06-14
(1) Chloe (Jester)
(2) Chloe (Plebian)
Command>
说明:

第一列
pub 表示是 master signing key 的公开部分
第二列
指示该 key 的位的长度,类型以及ID。D表示类型为 DSA; g表示是仅为加密的 ElGamal key ;G表示是 ElGamal key 它可用时用于加密和签名。
第三列
创建时间
第四列
过期时间
用户的ID也紧跟其后。

GnuPG1 与 GnuPG2 、GnuPG2.1 区别
https://superuser.com/questions/655246/are-gnupg-1-and-gnupg-2-compatible-with-each-other

GnuPG 1
gpg 仍然保留用作嵌入式和服务器端使用,这个更少依赖以及更小的二进制文件。 来自 man gpg :

This is the standalone version of gpg. For desktop use you should consider using gpg2.

GnuPG 2
gpg2 是 gpg 的重新设计版本—— 但是更多的是在内部级别的更改。较新的版本分为多个模块,例如,有可用于 X.509 的模块

来自 man gpg2

In contrast to the standalone version gpg, which is more suited for server and embedded platforms, this version is commonly installed under the name gpg2 and more targeted to the desktop as it requires several other modules to be installed.

GnuPG 2.1
GnuPG 2.1是一个重要的变化,它将以前分开的公钥和私钥(pubring.gpg vs secring.gpg)组合到公钥匙中。这是以兼容的方式实现的,所以当GnuPG 2.1集成了私有密钥环时,您仍然可以使用GnuPG 1,但私有密钥的更改不会出现在相应的其他实现中。

[…]允许与GnuPG 2.1共同存在较旧的GnuPG版本。 然而,使用新gpg的私钥的任何更改在使用2.1版本的GnuPG之前都不会出现,反之亦然。

emacs 中使用 GnuPG 来加解密注意事项
本人在使用的过程中,最好在 emacs orgmode 中使用 GnuPG1 来进行加解密。不然容易有一些其他的问题。比如这个:

https://emacs-china.org/t/org-crypt/2585