2010年6月19日星期六

[GFW BLOG] 个人数据安全 (1):用GnuPG保护个人隐私数据

作者:liancheng来源:http://blog.liancheng.info/?p=338

之前在Twitter上说过,打算写一个个人数据安全解决方案的系列,内容包括:
  • 基于GnuPG的个人隐私数据保护
  • 自建XMPP服务器保障即时通讯安全
  • 使用Dropbox进行较低密级的文件共享和协作

后记:后来觉得Dropbox这个话题太简单了点,没啥好写的,且重点在共享和协作,而非安全,便取消了。

原本还打算写一写用SSH端口转发隧道建立SOCKS v5代理(俗称SSH翻墙术),鉴于网上已经有不少不错的介绍(12),就不再重复劳动了。这里所采用的技术全部基于开源软件、免费软件或免费服务商,同时也兼顾使用体验。除了自建XMPP服务器所需的域名费用外,其余部分的经济成本为零。

跟丫头暂时还维持着北京、杭州两地分居的状况,网络是平时联络和数据交换的最为重要的手段。上述的这些技术都是我们目前正在使用的数据安全保障手段。这几篇文章的前身其实就是我写给丫头的操作手册。内容并不艰深,丫头并非计算机专业也能轻松掌握就是最佳佐证 :-D

另外,由于我平时主要使用Ubuntu,所以这里的所有方案都同时适用于Ubuntu和Windows。对Ubuntu以外的其他Linux发行版,这里就不兼顾了,不过方法都大同小异。

第一篇挑个复杂点儿的,讲讲GnuPG 8-)


本篇将讲述Windows和Ubuntu下的GnuPG解决方案,同时也会对GnuPG背后的信息安全原理做一些简单的科普。GnuPG可用于隐私数据的加密和签名,以便对其进行安全的传输和存储。除GnuPG外,本篇介绍的软件还包括Windows下的GnuPG ShellGPGee(GnuPG explorer extension)以及Ubuntu下的Seahorse

对于熟悉GnuPG加密、签名原理的读者,可以直接跳过科普的章节,直接阅读软件安装配置部分。

缘由

丫头平时记性都挺好,唯独记不住密码,各种帐号密码随设随忘。我则刚好反,平时啥啥都忘,唯独对各种随机字符串印象深刻。我自己的各个密码在各大网 站的密码强度评估也从来都是绿色。所以她的各种账户密码基本上都靠我来记,想不起来了就给我发个查询请求。有时候不光是密码,偶尔还需要互相备份网银、支 付宝之类的证书文件。这些都属于有高保密性要求的隐私数据。

丫头虽然不是计算机专业,不过在软件应用方面还是有相当的水准,我并不太担心她的机器上会有病毒或木马。所以在一定程度上说,密码、证书被盗的概率 实际上并不高。然而墙内信息安全形势之恶劣已经是众所周知,通过IM或邮件明文传输密码、证书总是件让人不放心的事情。即使我们所使用的服务都号称对通讯 做了加密,但出于众所周知的原因,国内的服务商们为了自身的生存,实际上都不得不在服务器端对解密后的明文数据做内容过滤和审查。因此也就存在着恶意个体 或团体有目的的盗取用户明文数据的可能。作为程序员,总有种如坐针毡的不爽,必须防患于未然。这个想法促使我去寻求一个相对严密且切实可行的保障隐私数据 安全的解决方案。

问题描述

解决信息安全问题的首要任务,就是确立威胁模型。简单来说就是将现实中存在的诸多威胁信息安全的因素分门别类,找出最需要解决的威胁因素。在这里,我们假设发件人和收件人的主机都是安全的,需要处理的威胁主要是来自数据传输通路上的数据监听、窃取、篡改和仿冒。

更精确一些,数据传输过程必须提供以下保障:

  1. 保密性:发件人所发出的消息必须是加密的,且只有特定的收件人才能够对密文进行解密
  2. 完整性:发件人所发出的消息必须原封不动地抵达收件人那里,如果沿途惨遭篡改、删节,收件人必须能够发现
  3. 身份验证:收件人能够验证发件人的身份,以保证其他人不能仿冒发件人的身份发送虚假消息

加密

要保障保密性,最简单的方法莫过于使用加密压缩包(Zip、7Zip、RAR等常用压缩格式都支持加密)。然而要采用这种方法,首先要把解压密钥交到收件人手中。如何安全地交换解压密钥?这就陷入了一个死循环。

双方使用同样的密钥对数据进行加密和解密,这种加密方式被称作对称加密,对应的密钥就被称作对称密钥。常用的对称加密算法,如RC4、3DES、 AES等,都具有高效的优点,即使是普通PC机也可以在短时间内使用这些算法对大量数据进行加解密。然而它们也都不可避免地具有加解密双方必须事先共享对 称密钥的先天缺陷。正是这个缺陷导致了上面鸡生蛋蛋生鸡的窘境。

相对于对称加密,非对称加密(或称公钥加密)则很好地克服了这个缺陷。非对称加密需要使用不止一个,而是一对密钥——一个公钥和一个私钥。明文数据 使用公私钥对中的一个密钥加密后,只能由对应的另一个密钥解密。应用非对称加密时,用户需要妥善保管私钥,不得外泄或丢失,同时公开公钥。

借助非对称加密,保密性基本得到解决。初始时,收件人生成一对密钥,并将公钥公布给发件人。双方收发消息时遵循一下流程:

  1. 发件人用收件人的公钥加密消息,生成密文并发送给收件人
  2. 收件人用自己的私钥解密消息密文,得到消息明文

看起来不错,但还有个问题:非对称加密虽然克服了需要事先交换对称密钥的问题,但常用的非对称加密算法(如RSA)都非常慢,无法在短时间内加密较 长的数据。假设我们要传输的不是密码这样的短文本,而是诸如照片等尺寸上兆的数据,上述过程就行不通了。对于这个问题,解决的方法也很简单。快速加解密是 对称加密的强项,那么我们就仍然使用对称加密来对数据进行加密,转而使用非对称加密来对对称密钥进行加密。这样一来,上述过程就变成:

  • 发件人
    1. 随机生成一个对称密钥
    2. 用对称密钥加密消息明文得到消息密文
    3. 用收件人的公钥加密对称密钥得到对称密钥密文
    4. 将消息密文和对称密钥密文一并发给收件人
  • 收件人
    1. 用私钥解密对称密钥密文得到对称密钥
    2. 用对称密钥解密消息密文得到消息明文

好吧,我承认有点像绕口令,但其实还是蛮简单的 :mrgreen:

数字签名

数字签名是一种用于鉴别发件人身份的技术。它主要应用了非对称加密和消息摘要。

消息摘要是将一段任意长度的消息转化成一个固定长度的短文本串的过程。对于信息安全领域所使用的摘要算法(如常用的MD5、SHA1),极难找到具有相同摘要的两段不同的消息。因此事实上只要消息摘要相同,就可认定消息相同。

对给定消息进行数字签名的过程如下:

  1. 计算消息摘要
  2. 用自己的私钥加密消息摘要,得到数字签名
  3. 将数字签名与消息一起发送给收件人

收件人收到消息后验证数字签名的过程如下:

  1. 计算消息摘要
  2. 使用发件人的公钥解密数字签名,得到原始消息摘要
  3. 比对两个消息摘要

若二者相同,即可证明该消息确实由拥有相应私钥的发件人发出,这就达到了身份验证的目的。

注意,在校验数字签名的过程中,消息完整性也得到了保证——由于数字签名中包含原始消息的摘要值,一旦消息遭到篡改,收件人计算出的消息摘要便会有别于数字签名中的原始消息摘要,从而导致验证失败。

至此,保密性完整性身份验证都圆满地得到了解决。完整的数据传输过程如下:

  • 发件人
    • 对消息进行数字签名
      1. 计算消息摘要
      2. 用自己的私钥加密消息摘要,得到数字签名
    • 加密签名后的消息
      1. 随机生成一个对称密钥
      2. 用对称密钥加密消息和数字签名,得到消息密文
      3. 用收件人的公钥加密对称密钥,得到对称密钥密文
      4. 将对称密钥密文和消息密文合并后发送给收件人
  • 收件人
    • 解密
      1. 用自己的私钥解密对称密钥
      2. 用对称密钥解密消息密文得到消息明文和数字签名
    • 校验数字签名
      1. 计算消息摘要
      2. 用发件人的公钥解密数字签名,得到原始消息摘要
      3. 比对两个消息摘要

以上简要解释了加密和签名的密码学原理。它们是我们的个人数据安全解决方案中最为核心的两个操作。实际上,日常生活中很多常用的信息安全保障手段,如SSL/TLS证书、网银证书、支付宝证书等等,也都在是以这两个操作为核心的。

在实际应用中,可以根据需要对加密和签名操作进行组合,例如:

  • 只加密不签名

    对隐秘文件进行备份时可采用这种方法。因为日后读取该文件的还是你自己,所以签名与否并不重要。值得注意的是,非对称密钥的长度往往很长,一般至少 在1024 bit(128字节)以上,而用户选择的对称密钥则往往只有几个或十几个字节。因此一般而言,非对称加密的强度要远远高于对称加密。

  • 只签名不加密

    通过Email向公众发布重大消息时可采用这种方法。消息内容本身是公开的,因此不用加密。数字签名则可用于校验消息来源,同时防止他人仿冒发件人身份发布虚假消息。

  • 签名且加密

    一切同时强调保密性和发件人身份验证的用例都应采用这种方法。

GnuPG

呼~经过一大段的科普,现在总算要进入正题了 :-P

GnuPG(或称GPG),全称是GNU Personal Guard,它综合了上述的加密和签名技术,可为个人隐私数据提供可靠的保护。GnuPG是GNU对OpenPGP(或简称PGP)标准(RFC 4880)的实现。GnuPG剔除了OpenPGP标准中的专利算法,是完全开放和免费的开源软件。关于OpenPGP、PGP、GnuPG的关系和区别,可以参见RFC 4880 1.1节。另外,在对数据进行加密的同时GnuPG还会顺带进行压缩。

GnuPG软件本身虽然是跨平台的,但它只提供了一套命令行工具,对于普通用户而言操作过于繁琐。因此,各种GnuPG的图形前端被开发出来用以简 化用户对隐私数据的加密、签名过程。以下分别对Windows和Ubuntu下的GnuPG图形前端的安装、配置和使用做一个简要介绍。

在Windows下使用GnuPG

软件配置

需要安装的软件如下:

  1. GnuPG

    此处下载。GnuPG是整个解决方案的核心,提供了一系列实现加密、解密、签名、证书管理等功能的命令行工具。GnuPG Shell和GPGee都需要借助GnuPG才能工作。

  2. GnuPG  Shell

    此处下载。GnuPG Shell是GnuPG的一个图形前端,可以较为方便地完成证书管理的工作。GnuPG Shell当然也可以用于文件的加密、解密和签名操作,但是其使用不如GPGee那样来得简单直接。

  3. GPGee

    此处下 载。GPGee全称为GPG explorer extension。它在Windows Explorer的右键菜单中增加了GPG相关的菜单项,使得用户可以非常方便地执行加密、解密和签名操作。但GPGee不提供GnuPG证书的管理功 能,因此建议和GnuPG Shell配合使用。

    菜单项“Sign & Encrypt”和“Sign”的含义不言自明。菜单项“Encrypt (PK)”中的PK是Public Key(公钥)的缩写,选择该菜单项可对文件进行非对称加密(公钥加密)。相应的,“Encrypt (Symmetric)”用于对文件进行对称加密,类似于使用RAR或Zip制作加密压缩包。

如果先安装GnuPG再安装GnuPG Shell,则后者会自动检测出GnuPG的安装路径,无须另外的配置。GPGee则需要手工配置GnuPG相关路径。

在GPGee菜单项中选择“Configure”进入GPGee配置对话框,有三个文件的路径需要配置,包括:

  • GnuPG主程序 :即GnuPG安装目录下的gpg.exe
  • 公钥密钥环:位于%APPDATA%\gnupg\pubring.gpg
  • 私钥密钥环:位于%APPDATA%\gnupg\secring.gpg

其中两个密钥环文件用于存储和管理GnuPG系统中所有已知的公钥和私钥。

生成密钥

借助GnuPG Shell可以方便地生成密钥:

  • 选择菜单项“Keys/Generate New…”,打开密钥生成向导
  • 设置新密钥的基本用户信息
  • 选择“Advanced…”,设置密钥长度和有效期
    • 密钥长度越长安全性越高,但加密、解密速度越慢。出于安全性考虑,推荐至少设置为2048。
    • 密钥在有效期之后便会失效,不能再用于加密、解密或签名操作,必须重新生成密钥。默认有效期为永久有效。出于安全性考虑,推荐设置有效期为1年。
  • 设置私钥通行码(passphrase)
    • 通行码是用于保护私钥的密码,每次使用私钥进行加密、解密、签名操作时都需要输入通行码。
    • 一旦私钥丢失,通行码将是保护私钥的最后一道屏障,因此应具备一定的长度和复杂度。

录入并确认以上信息后,GnuPG Shell便会开始生成密钥。根据用户选择的密钥长度和机器的性能,密钥生成时间从几十秒到几分钟不等。密钥生成完毕后,便可在GnuPG Shell的密钥列表中看到新密钥了。同时,你会看到新密钥有一个对应的8位的Key ID,它实际上唯一标识了新密钥的公钥。Key ID的作用将在后面提及。

公钥发布与密钥服务器

生成新密钥后,剩下的事情就是和你的朋友们互相交换公钥,然后你们便可以安全地进行数据交换了。

也许你已经意识到一个重要问题,就是公钥的发布过程可能被人做手脚:如果某人制作了一对密钥,并伪装成你的朋友来和你交换公钥,那么基于公私钥认证的整个信任体系便从根基上被瓦解了。因此,必须以某种可信的方式交换公钥——比如将公钥写在纸上交给对方。

然而非对称密钥往往有成百上千个字节那么长,将其抄到纸上或是敲到电脑里无疑是傻得要命的事情。你应该还记得刚才提到的Key ID吧?这时就是它发挥作用的时候了。如果我们把公钥都发布到一个公共的地方,然后只在纸上互相交换8位的Key ID,再用Key ID到这个公共的地方下载对应的公钥,就可以安全且方便地交换公钥了。而这个公共的地方,就是密钥服务器(Key Server)。GnuPG Shell内置了对密钥服务器的支持,可以直接向服务器发布新密钥或通过Key ID获取已经发不到服务器上的其他密钥。其使用方法也比较简单直接,这里就不赘述了。

如果你和你的朋友可以有效地互相确认身份,那么也可以在不借助密钥服务器的情况下手动导出、导入公钥来进行交换。方法是在GnuPG Shell密钥列表中选择新密钥并点击工具栏上的“导出”按钮。然后你便可以将导出的公钥文件发送给其他人,同时索要他们的公钥并导入GnuPG Shell。记住,除非你们能够有效地确认对方的身份,否则不要使用这种方式交换公钥!因为公钥文件在网络传输过程中可能被劫持和篡改。这也是为什么银行 总是鼓励用户使用USB硬件证书(比如招行的U盾),因为将密钥以物理方式刻录在硬件中发布给用户在要比通过网络发送密钥安全得多,尤其是在用户随时可能 处于不安全的网络中时更是如此。

在Ubuntu下使用GnuPG

Ubuntu用户很幸运,Seahorse作为一个通用的密码/密钥管理器,对GnuPG提供了良好的支持,同时也支持密钥服务器。更棒的是,Seahorse还提供了若干GNOME插件,实现了类似GPGee的右键菜单功能,算是非常整齐划一的解决方案 :-D

安装过程非常简单:

sudo aptitude install gnupg seahorse seahorse-plugins

注意生成密钥时选择PGP密钥。其他步骤和在Windows下使用GnuPG Shell基本相同,就不赘述了。

结语

OpenPGP标准以及GnuPG作为成熟的个人隐私数据安全保障方案,已经有十多年的历史了。它们也经常被集成在邮件客户端中,为Email服务 提供加密和数字签名支持。然而各种邮件客户端的PGP支持在质量和兼容性上参差不齐,用起来往往问题多多。比如我曾在Thunderbird中使用过 Enigmail,结果遇到了让人头疼不已的中文编码问题,好不容易解决后,又发现跟同事使用的Outlook、Foxmail存在兼容性问题,最终不得 不放弃。尔后我又尝试在Firefox中使用FireGPG访问Gmail,更是令Firefox直接崩溃……这也是我不选择Email PGP方案转而直接采用更为通用的GnuPG的原因。

记得前几年,学校里曾经刮起过一阵互换PGP/GPG Key ID的风潮。可怜我当时连PGP/GPG为何物都不知道。不想现在却和丫头用得不亦乐乎。

最后,希望这篇拙文能够在恶劣的大环境下帮助到更多人安全地完成数据交换,也就不枉我码这么多字的辛苦了 8-)


P.S.: 第一次给图片打马赛克,GIMP的高斯模糊滤镜还真是蛮好用的 :mrgreen:




--
Posted By GFW BLOG 功夫网 to GFW BLOG at 6/19/2010 07:50:00 PM

--
1、请点击www.chinagfw.org访问我们,订阅地址:http://feeds2.feedburner.com/chinagfwblog。2、翻墙利器"赛风"(Psiphon)代理新网址:http://wrcaonima.info/。3、本站热烈欢迎各位朋友投稿或推荐文章,请发邮件至chinagfwblog[at]gmail.com。
停止订阅,请发邮件到
gfw-blog+unsubscribe@googlegroups.com

没有评论:

发表评论