使用GnuPG加密和签名
PGP的出现
PGP是一套用于消息加密、验证的应用程序,其加密/验证机制采用名为IDEA算法的散列算法。PGP及其同类产品均遵守OpenPGP数据加解密标准。
但是PGP的普及并非一帆风顺,PGP的主要开发者Philip R. Zimmermann,在1991年的时候将源码放到了互联网上。由于美国在当时对于加解密算法和软件的出口有严格的限制,Zimmermann被FBI侦讯达数年。不过,美国是保护个人著作的。于是,Zimmermann在志愿者的帮助下,将PGP的源码被出版为书,销往欧洲,由于合法,所以才有了今天的普及。
而由于PGP是商业软件,GnuPG是遵循OpenPGP数据加解密标准的自由软件实现,中文译为GNU隐私卫士,卫士之名当之无愧,不像某些公司,阿猫阿狗都敢叫卫士。
对称加密和非对称加密
-
对称加密 简单的说,加密和解密时使用相同的密钥即对称加密,比如我们日常使用的压缩软件加密使用的就是对称加密。
-
非对称加密 采用这种方法,首先需要生成一对密钥。公开发布出去的称为公钥,用户自己保密的称为私钥。公钥用来加密,私钥用来解密。
RSA算法
RSA加 密算法是常用的非对称加密算法,一般认为RSA是1977年由在MIT工作的Ron Rivest、Adi Shamir和Leonard Adleman一起提出的,其实早在1973年,在英国政府通讯总部工作的数学家Clifford Cocks在一个内部文件中提出了一个相同的算法,但他的发现被列入机密,一直到1997年才被发表。
RSA算法的可靠性
要知道,没有绝对的安全,但是要破解RSA需要相当长的时间或是很大的代价,就可以认为它是安全的。
-
密钥长度是256位,个人电脑几小时就能分解其因子。
-
1999年,数百台电脑合作分解了512位长的密钥。
-
1994年Peter Shor)证明一台量子计算机可以在多项式时间内进行因数分解。
对极大整数做因数分解的难度决定了RSA算法的可靠性。 今天只有短的RSA钥匙才可能被强力方式解破。到2013年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
因此,未来出现了量子计算机,或者找到了一种有效分解大整数的算法,RSA就被看作是不可靠的。 看到这,你应该明白,一定要用4096位长的密钥。
使用GnuPG
安装GnuPG
生成钥匙对
$ gpg --gen-key
接着会出现算法选择的问题:
gpg (GnuPG) 1.0.7; Copyright (C) 2002 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. 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?
默认的是RSA,既支持加密也支持签名,输入1并回车。接着选择密钥长度:
RSA keypair will have 1024 bits. RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048)2048
默认的长度是2048位,直接回车即可。不过俺强烈建议使用4096位,输入4096并回车,接下来选择钥匙有效期限:
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
默认永久有效,建议输入一个有效期限并回车,120表示120天,24w表示24个星期,6m表示6个月,1y表示1年。 我用的默认永久有效,直接回车。问你是否确定,输入y并回车。
接着填写个人信息:
GnuPG needs to construct a user ID to identify your key. Real name: ibrother Email address: ibrother.linux@gmail.com Comment: ibrother in github You selected this USER-ID: "ibrother (ibrother in github) " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
这3行个人信息将用于产生钥匙的uid 第1行建议填写网名,比如俺常用的网名是ibrother。 第2行填写你的email地址,比如俺的邮箱ibrother.linux@gmail.com 第3行是备注,用于进一步标明身份。
接下来,输入密码用于保护私钥,程序就会开始生成钥匙对,过程可能几秒钟到几分钟。此时,动动鼠标让电脑工作起来有助于产生足够的随机数。
You need a Passphrase to protect your secret key. Enter passphrase:
一旦生成钥匙对,强烈建议立即生成注销证书
首先查看一下公钥ID
$ gpg --list-keys--list-keys /home/ibrother/.gnupg/pubring.gpg --------------------------------- pub 2048R/A0A2A2F8 2014-07-09 uid [ultimate] ibrother (ibrother in github) sub 2048R/4AAB15B9 2014-07-09
生成注销证书
gpg --output revoke.asc --gen-revoke A0A2A2F8 sec 2048R/A0A2A2F8 2014-07-09 ibrother (ibrother in github) Create a revocation certificate for this key? y Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 1 Enter an optional description; end it with an empty line: > Someone cracked me and got my key and passphrase > Reason for revocation: Key has been compromised Someone cracked me and got my key and passphrase Is this okay? y You need a passphrase to unlock the secret key for user: "ibrother (ibrother in github) " 2048-bit RSA key, ID A0A2A2F8, created 2014-07-09 ASCII armored output forced. Revocation certificate created. Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable. It is smart to print this certificate and store it away, just in case your media become unreadable. But have some caution: The print system of your machine might store the data and make it available to others!
注销证书已经生成,请妥善保管。如果不小心被人盗取了密码,这是你注销公钥的唯一凭证。
发布公钥
由于是公钥加密,我们必须将公钥发布出去,有以下两种方法:
导出公钥
$ gpg -a --output key.public --export UID
把UID替换成你的名字或email地址。会在当前工作目录得到key.public文件,使用以下命令查看内容:
$ cat key.public
内容类似如下:
-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2 ....... -----END PGP PUBLIC KEY BLOCK-----
这样你就可以把公钥放在博客上,或者email给你的小伙伴。另一种方法是将公钥发送至公钥服务器:
把公钥发布到公钥服务器
$ gpg --keyserver keys.gnupg.net --send-key ID
只需要将ID替换成你的公钥ID。
以上说的是发布你的公钥,这样小伙伴就可以发送加密的文件或邮件给你,那么如何发送加密文件或邮件给小伙伴呢?这就需要获取小伙伴的公钥。
导入公钥
$ gpg --keyserver keys.gnupg.net -recv-key 0xA0A2A2F8
0xA0A2A2F8是俺的公钥id,替换成你的小伙伴的公钥id
或者导入公钥文件
$ gpg --import key.public
由于公钥加密的特点,公钥的发布过程,和获取公钥的过程必须保证可靠性,因此有了指纹验证:
验证指纹并签收公钥
$ gpg --fingerprint
输出应该包含如下所示:
pub 2048R/A0A2A2F8 2014-07-09 Key fingerprint = DE91 71DC AE38 DE8E AB5A C423 3E6A 8CC1 A0A2 A2F8 uid [ultimate] ibrother (ibrother in github) ibrother.linux@gmail.com sub 2048R/4AAB15B9 2014-07-09
其中“DE91 71DC AE38 DE8E AB5A C423 3E6A 8CC1 A0A2 A2F8”就是这个公钥的指纹,和小伙伴核对确认无误后就可以签收了:
$ gpg --sign-key ibrother
加密文件
$ gpg -a --output message-ciper.txt -r ibrother -e message.txt
参数说明:
- -a输出文本格式
- --output指定输出文件名
- -r知道接收者的公钥uid
- -e表示执行加密操作
如果加密二进制文件不需要-a参数
解密文件
$ gpg --output message-plain.txt -d message-ciper.txt
参数说明:
- --output指定解密后的文件名
- -d表示执行解密操作
签名一个文件
独立签名文件签名方式
$ gpg -a -b message.txt
独立签名方式是原文件和签名文件分开,可以用如下命令验证签名:
$ gpg --verify message.txt.asc
输出一定要有“Good signature”字样,就说明验证成功。
clear签名方式
$ gpg -a --clearsign message.txt
使用如下命令提取原始信息:
$ gpg --output message-original.txt -d message.txt.asc
GnuPG和mutt的整合
关于mutt的初步配置,建议看俺之前的博文
一旦mutt安装好后,在/usr/share/doc/mutt-1.5.22-r3/samples/目录下可以找到gpg.rc.bz2
文件
$ bzcat /usr/share/doc/mutt-1.5.22-r3/samples/gpg.rc.bz2 >> .mutt/gpg.rc $ echo echo "source ~/.mutt/gpg.rc" >> .muttrc
然后编辑~/.mutt/gpg.rc
,编辑或者加入以下几行
set pgp_good_sign="^\\[GNUPG:\\] GOODSIG" set pgp_sign_as = 0xA0A2A2F8 set pgp_timeout = 3600 set crypt_autosign = yes set crypt_replyencrypt = yes
将0xA0A2A2F8改为你自己的公钥id。这样使用mutt发送邮件默认使用签名。
在mutt的发信界面可以选择其他选项:
输入P
e表示只加密,s表示签名,b表示既加密又签名,c表示不进行加密和签名
收信界面,有s的即标明签名邮件
如果有公钥的话,查看邮件,mutt会自动验证签名,给给出提示信息:
其他邮件客户端支持
-
Linux用户可以使用Thunderbird,KDE桌面用户建议使用Kmail,Kmail对Gmail有更好的支持。
-
OS X自家的Mail就可以支持gpg邮件加密
-
Windows用户推荐Thunderbird