使用 GnuPG 实现电子邮件加密和数字签名——PGP 30分钟简明教程(1)

  • update 2013-05-14:之前写得可能有点晦涩难懂了,这次更新重新组织一下内容,先阐述最简单和容易实现的操作——邮件加密和签名,着重以图形工具讲解。然后放在第二篇再讲解命令行工具,以及对文件进行加密和数字签名的方法。

PGP (Pretty Good Privacy) 是由 Phil Zimmermann (之所以提这个名字是因为这位仁兄背后有一段故事,有兴趣可以找找他的八卦)于 1991 开发的一个用于数据加密和数字签名的程序,由于被广泛应用,以至于后来形成一个开放的标准 OpenPGP,这个标准也是目前最为常用的邮件加密和签名的方式。而 GnuPG 则是实现了该标准的一个开源免费程序,本文将会简单介绍如何使用 GnuPG 管理钥匙、加密/解密文件和电子邮件、数字签名文件和电子邮件。篇幅有点长,一共分两章,不过内容是很简单的。@ivarptr

目录:

  • 加密和数字签名的简单原理
  • 下载并安装 GnuPG
  • 使用(图形化)工具管理钥匙
  • 邮件的加密和数字签名
  • 使用命令行管理钥匙
  • 使用命令行加密解密文件
  • 使用命令行对文件进行数字签名
  • GnuPG 的更多指南

一、加密和数字签名的简单原理

首先每位用户都需要用 GnuPG 程序生成地球上惟一的一对钥匙,分别称为公钥和私钥(即 public key 和 private/secret key)。公钥用于加密、私钥用于解密。使用公钥加密过的信息只能由配对的私钥解开。这种加密方式叫做非对称加密。

非对称加密的过程是:如果A君要发送信息给B君,首先B君得把自己的公钥扔出来,A君得获取B君的公钥后用B君的公钥加密信息并发送过去,B君收到(加过密的)信息使用自己的私钥解密就可以还原信息了。

在数字签名时,私钥用于签名、公钥用于核对签名。

数字签名的过程是:如果A君要发送信息给B君,信息首先会被计算出一个指纹值(比如MD5值),然后A君使用自己的私钥加密信息和这个指纹值(这个过程称为签名)并发送出去,接受者B君收到信息之后使用A君的公钥来解密并重新核对一次信息的指纹值,这样B君就可以核对信息有无被篡改以及是否真的为A君所发出的了。

二、下载并安装 GnuPG

GnuPG 是一个集钥匙管理、加密解密、数字签名于一身的工具,对于 Linux 系统,一般可以在系统本身的软件源找到 GnuPG,比如对于 ArchLinux 可以使用如下命令安装:

$ sudo pacman -S gnupg

对于 Windows 系统可以下载免费开源程序包 GPG4Win,建议下载完全版,里面既包含了 GnuPG 命令行工具,又有图形化的钥匙管理工具 Kleopatra 和邮件客户端程序 Claws Mail。对于Mac OSX 系统则可以使用 GPGTools

更多的相关工具可以在这里找到

三、使用(图形化)工具管理钥匙

上一节提到,在不同的平台下所使用的管理工具各不相同,幸运的是他们的功能大同小异,而且界面简单,相信只要你一运行则不用看教程都会使用。下面就提一下使用要点:

seahorse

 

[图1] Linux Gnome 桌面环境自带的钥匙管理工具 seahorse

1、生成钥匙对。一般点击“文件”菜单就会找到“新建PGP钥匙”的选项,跟着提示输入你的名字(建议使用你常用的网名)、email地址以及备注(可以不填)就会生成一个属于你自己的钥匙对。期间会提示你输入一个密码,这个密码是用于保护你的私钥,建议使用比较复杂的密码。

2、发布你的公钥。因为你的朋友要发送加密信息给你则必须要先获取你的公钥,所以,作为一个有礼貌的 GnuPG 用户应该先发为敬。Internet上有很多免费的公钥服务器,你可以把你的公钥发布到随便一个服务器,它们之间会自动同步(最长可能需要几小时或者几天)。在管理工具里选定你的钥匙对,然后选择类似“发布”或者“远程-同步”之类的选项即可。在发布的时候工具可能会询问你使用哪个公钥服务器,正如刚才所说的,随便选一个就可以了。

3、获取你朋友的公钥(或者让朋友获取你的公钥)。在管理工具里选择类似“搜索”或者“远程-查找钥匙”,在搜索框里填写对方的email地址或者生成钥匙时所填写的名字,然后点击搜索就可以找到对方的公钥。作为练习,你可以搜索自己的公钥,如果搜索没有结果则可能时因为服务器还没同步,可以过几分钟再试试。或者搜索我的公钥,我公钥的 email 地址为 ivarptr@126.com。点击选中搜索结果,然后再选“导入”即完成。

4、签收(sign)公钥。为了安全起见,获取你朋友的公钥之后,还需要跟对方核对一下这个公钥是否真的为他所拥有(因为可能存在假冒的情况)。核对的方法是选中你朋友的公钥,再选择类似“属性”或者“详细信息”的选项,其中你可以看到这个钥匙的指纹值,你可以通过电话、聊天工具或者email跟你的朋友核对一下,如果指纹值相同,则点击“签收这个钥匙(sign this key)”,这样就表示你正式可用这个公钥了。如果上一步你导入了我的公钥,则看看指纹值是否为“0D24 0A94 A86C 7B83 3F7C 200E 1CAF 0CB0 72E7 5B05“,这个是我钥匙的指纹值,无误的话就可以点击签收了。(补充:为了避免跟“数字签名”这个名词相冲突,这里我把“sign”书写为“签收”,在一些教程里可能会翻译为“签名钥匙”)

好了,下面我们就可以开始邮件加密和数字签名噜。

四、邮件加密和数字签名

实现邮件加密和数字签名一般需要使用邮件客户端软件,现在一般比较完善的邮件客户端工具都内置集成 OpenPGP 的功能,即本身就可以无缝地使用 GnuPG。比如 Evolution、KMail、Mozilla Thunderbird,对于 Windows 和 Mac OSX 系统,我比较推荐 Thunderbird,这也是一个开源免费程序。谷歌告诉我 Windows 下的 Outlook 和 Live Mail 也支持但我没有试验过,如果不行又懒得下载 Thunderbird,那么使用 GPG4Win 附带的 Claws Mail 也是可以的。因为各个邮件客户端的设置大同小异,下面我以 Evolution 为例简单介绍如何设置。

其实关键的设置只有一步,就是关联你的 email 帐号和你的钥匙id。在 Evolution 的帐号属性里,转到 Security 页,在 OpenPGP Key Id 里输入你的钥匙的id(即生成钥匙对时所填写的名字)或者email地址即可。如下图:

evolution-pgp-setting

[图2] Evolution 的邮件帐号设置窗口

设置就这么简单。然后在每次写 email 时点击菜单的 Options 勾选 OpenPGP 签名或者/以及加密,然后再发送即可。如下图:

evolution-pgp-write

[图3] Evolution 的书写邮件窗口

对方收到邮件时,Evolution 会自动检验签名或者自动解密邮件内容。需要注意的是,再发送加密邮件给你的朋友之前,你要先获取他的公钥(见本文第2节)。

小练习:尝试用邮件客户端发送一封签名或者加密过的邮件给我:ivarptr@126.com。

提示1:在签名或者解密时,有可能会弹出一个窗口要求你输入一个密码,这个密码就是生成钥匙对时设置的密码。

提示2:用网易邮箱收取签过名(而未加密)的邮件时可能会显示检验失败,这是因为网易邮箱会在邮件末尾添加附件的下载地址,相当于更改了邮件的原始内容,所以签名检验失败是肯定的。

好了,如果你只需要电子邮件加密和数字签名,这篇教程到此为止了。如果你喜欢折腾以及对 OpenPGP 好奇,点击这里继续阅读本教程的第二章《使用 GnuPG 实现文件加密和数字签名——PGP 30分钟简明教程(2)》

36 thoughts on “使用 GnuPG 实现电子邮件加密和数字签名——PGP 30分钟简明教程(1)”

  1. 居然没人留言!!
    ————–
    lz我照你的方法做了,从头看到最后(没想到文章居然这么长我还看完了)

    里面的小练习
    ————–
    1 —–BEGIN PGP MESSAGE—–
    2 Version: GnuPG v1.4.5 (GNU/Linux)
    3
    4 hQEMA7YbZFB08PX5AQgAhohSuSwK63pQIflU01vOOpcww/eyCiKosIxJhbaPEvtW
    5 kEnHV6FTKn+77fXgTV+sNRjW5TzbDN0V6O4ZjoPH8uFZVEcYQRasNtH5t0LRm95U
    6 uzRuNWIbqgZVGNh/pfBtkEpv/Y6zRyPFSgXxjoGCl648KqBTeqzBLIZyCQ8dAmkO
    7 Ul7kR+c163jVS+5Kunl0kB7LjbcMKA1lrQXjlWCyio+UoFby033FSP6mxmr0J0J/
    8 5XS1HoR8zubaZDi/agZyN/Q7Pu+3oqSyjnffc1Czh1qz8uegvq8XoD6KEiVOckFz
    9 hoQJDSTOFfXrSMnzDy2FYOOhqy1pXmaG44nO4fc8WtJ3AZ9nVWvlWx6rZ2nWQ86r
    10 thSSyT/RM2kYo8drRhWBXm17Kx7oQftA9qgbeZcxUch9FrjRoowCbmg/QubtL76Z
    11 9/OhhKkz2O1NiYoz/sxOvlfw+8YN1fByO3z9fKjoOp8Sf4t1YnE0rnDPvsBJ4KWq
    12 2IzIiEJ56ck=
    13 =51f8
    14 —–END PGP MESSAGE—–
    ———————————————uid就是我评论里的用户名和邮箱了————

    你这部分的数字签名我没成功

    命令运行后同样会生成一个文件 message.txt.asc,内容如下:

    —–BEGIN PGP SIGNED MESSAGE—–
    Hash: SHA1

    hello world, my key id is 72E75B05, finger is 0D24 0A94……5B05, check it
    out.
    —–BEGIN PGP SIGNATURE—–
    Version: GnuPG v2.0.19 (GNU/Linux)

    iQEcBAEBAgAGBQJRbuXuAAoJEByvDLBy51sFaY8IAKKnXX2JGI51mzYSakqvhNnr
    iV2JLvokMkvyDuJQGeNDMim5W7P0/df+G4oO45B9b0iFx6DSQwZGeBjEGCXvCURa
    uU2fdEqjaSarlrs0d4R1ihol8rCxkZwBYBBPjcvDkVwoVJJYS0zc3OYzMvWhb8mk
    Q72wQ0obX5LedUVrauG9OLkvq9aBKONr6Xlkldd133v3gb/Wzjf71CLYcRoJDpze
    2XBSkrGS0UxRp3WixJJK8xyfDfI9VHBaXEndCkgQ+Mpfq9nV5XAm3MKcPjlENq4g
    xGywHRpnwpW8N22VE6ZFEUFlXrh5C8hZfGaG/EcT21PeAbZYH8RcnYTbJ+s2nZ4=
    =lhd6
    —–END PGP SIGNATURE—–

    出错信息如下

    gpg –verify aa.asc
    gpg: 找不到有效的 OpenPGP 数据。
    gpg: 签名无法被验证。
    请记住签名文件(.sig或.asc)
    应该是在命令行中给定的第一个文件。

    gpg –output xxz -d aa.asc
    gpg: 找不到有效的 OpenPGP 数据。
    gpg: decrypt_message failed: eof

    ———————-
    最后感谢你的好文,期待回复

    1. 呵呵,你的留言解密之后是:
      “hi ,i am testing. thanks for your post
      感谢你啦”

      至于签名验证没通过,这是我的问题,原来wordpress的引用格式会把两条横线符号合并成一个长横线符号,现在我已经把它编辑过来修正了,你可以重新复制粘贴到本机再试试。

  2. hi,

    第四步用GPG加密邮件,填写了我的公钥ID (如 图1), 尝试发送邮件报错 (如 图2),请问我的设置有什么问题么?

    谢谢

  3. Could not create message.

    Because “gpg: skipped “18F67248”: No secret key
    gpg: signing failed: No secret key
    “, you may need to select different mail options.

  4. and I have one more question about:

    对方收到邮件时,Evolution 会自动检验签名或者自动解密邮件内容。需要注意的是,再发送加密邮件给你的朋友之前,你要先获取他的公钥(见本文第2节)。

    while when we configure the evolution gpg security function, we did not use the receiver’s pubkey, we just fill in the pubkey of ourselves’, am I right?

    or we should fill in the receiver’s pubkey instead of pubkey of ourselves in the evolution security configuration (like [图2] Evolution 的邮件帐号设置窗口)???

    1. 你的第一个问题,估计是在[图2] Evolution 的邮件帐号设置窗口里面填写错id了,所填写的应该是自己的key user id,当然也可以填写自己的email地址(只要你在生成key时填写的email地址跟这个email地址一致就可以的了)。

      加密邮件使用接收者的public key,数字签名使用自己的 private key。

      所以在加密邮件时,一旦点击发送,Evolution会根据接收者的email地址寻找他的public key,如果你的 gpg 的钥匙环里面没有对方的public key,就会出错。

  5. —–BEGIN PGP MESSAGE—–

    wcBMA8ytcA6JTWtBAQf8C8UrZGf4ZD1+7MkTWJ8AlBZ3gifBSyh2MQrCAzvy9nQti75vDzUV7o3v
    78ZKb/gwzF1TLQ9u4ZQ/hhvvNRURsiYBJ/fHsVDGBlntvnvcRHi3ODozxUViPgmgjH7dOUdXj8uN
    xHF/irjY3+Yw/kvw/hqk5ZgvCKw146lQ9mW3x/WE7O2VJgujpZwe+n/9tj+9ZQflPRPD3sVB3VIu
    cGbxhfdtTK9F3iNuzD3r0bbukAEP292IfVMG9cnzeX0un7bE5PYWW5Omu0xG17fQ4ymqz+N8512C
    VsrS9O2FRC4h3b8TogwgzQJiEKZSQ54uM5rME/XkIAkfiIazKl+OKjUyJNLAggGFRMnx8Qkx0A10
    zwMPqbl14dilSrqAsRQ0zX3gqOeQlM2EJBRkpXdZfF9C/XPSncaLXopfrI1FKN3B4lgald+KpLa4
    6FQd7SvCIQZTao4NTazAGty/wexk4YJ9J93+/XlEETM7I8fMV/B7Q/57ZdMNBR9m4Gw9orLjlU4J
    y3gLsX5yHpSYNlT+we4ozzVNtdnQi9AoOcY/zz/FVghuYFjI/O+JolCxYHMI4YNBpPr7IJBCNxG6
    ZS+AKUGiI6Ks25VDtd4MRM3zjMgxNoIw0IsRwjAGLwUCS1cCtTdMqMztcpakjYemgCzb/E6uo6hI
    +7BHxBeOtIYrI8EDZwJyNLqXFgIP+evcwrHVNuRH/WAD1PNk0VZ93eNgPakH7w6VkA8cIifyMgvG
    8ll4gErKXJMmCx3vFH2haiHW0w0nP/Du7vw=
    =Eljx
    —–END PGP MESSAGE—–

    人家给我发的这个短信,我怎么解密呢?

    1. 你把它复制到记事本保存为一个文件(假设文件名是 abc.txt),然后执行命令 gpg -d abc.txt 就可以解密了。

  6. 唉,我没有成功,总是提示:建立smtp会话时发生错误,请问我该怎么办呢?

  7. ivarptr,文章中没找到你的公钥,所以我表示很困惑。。

    后来发现,http://sks.pkqs.net/网站上可以查找已经发布的公钥,

    我就选择了这个sig sig3 72E75B05 2015-10-19 __________ 2025-10-16 [selfsig]

    所以你能收到我发送的邮件嘛

    谢谢

Leave a Reply

Your email address will not be published. Required fields are marked *