级别: 初级 Gary McGrawReliable Software Technologies John ViegaReliable Software Technologies
2000 年 5 月 30 日 在有关密码术三部分文章的第一篇(本文)中,Gary 和 John 讨论了设计密码系统要满足的目标,以及这些系统中可能出现的问题。另外,他们还讨论了计算机出现之前的密码术,以解释现代算法所依据的基础。
密码术是大多数开发人员都了解一些的主题 - 通常正好足够危险。最常见的错误包括在需要密码术时不使用,甚至在已正确确定需要时错误地应用密码术。错误使用(或不使用)密码术的通常结果是软件应用程序易受各种攻击。在软件安全性专栏的下三部分中,我们将讨论以下三个密码术主题:
- 何时以及如何使用密码术
- 密码算法的主要类别
- 何时以及如何应用特定算法
三部分可能看起来有些多,但实际上却不是。密码术是一个具有很多有趣方面和微妙事项的庞大领域。无法在有限篇幅里完整地评述这个主题。这需要一整本来评述它。好消息是有几本好书专门讲述密码术。我们极力推荐 Bruce Schneier 的
Applied Cryptography(请参阅
参考资料),该书的优点在于内容十分详尽,并适用于所有读者,包括有很少或没有密码术经验的人。Schneier 的书不仅比我们的文章详尽,而且还包括本专栏未讨论的相当深奥的算法。例如,如果要实现安全投票协议 - 在该协议中,没有外人可以猜出您投票给谁而且没有人可以伪造投票 - 该书将告诉您如何做到这一点。而本专栏则不包括。我们只在这里讨论最重要和最常见的问题。我们所讨论的内容应该可以给您以足够的概述,以便可以在大多数情况下智能地将密码术添加到软件中。毕竟,您有可能是程序员,而不是密码员。
在有关该主题的三部分文章的第一篇(本文)中,我们通过提供有关密码术的某些背景来作些准备。我们将讨论密码术系统设计满足的目标。然后将讨论这些系统中将出现何种问题。最后,将简述计算机出现之前的传统密码术,以便可以理解构建现代算法的基础。要知道人们加扰消息已有数千年,在其中学到了一些有用的东西。
下一部分,将讨论密码算法的两个主要类别:
对称(秘钥)密码术和
公钥密码术。第三部分,将讨论其它几个常见密码算法及其应用,包括密码散列算法和数字签名。
这里暂时不打算深究任何代码。几个月后,我们将重新讨论主题,并实际运用某些常见的密码库。现在,只让您感受一下算法的类型,应使用哪些算法,应避免哪些以及经常会遇到的常见陷阱。
密码术最终目标
密码术是“保护”数据的科学。密码术算法可以帮助提供四种类型的安全性:
机密性:确保数据的机密性,以使只有授权的团体才能够理解数据。这里不是试图对未授权团体隐藏某些数据(可能快速通过网线)。事实上,只要他们不理解数据甚至还可以复制数据。这里只不过是通过加扰数据来控制访问。大多数情况下,必须通过不安全媒体(如计算机网络)来传送敏感数据,同时还要保持机密。只允许授权的人理解数据。
通常将术语
已授权大致定义成暗示允许拥有特定秘密(通常是密码密钥)的任何人将数据解码并因而理解数据。在理想化世界里,可以制作一个要读取特定数据的人员列表,而世界上没有其他人可以读取该数据。实际上,通过加密提供机密性 -- 使用某些特殊信息和专门密码算法来加扰消息。加密之前的原始消息称为
明文。加密之后的被加扰消息称为
密文。密码算法本身常称为
密码。通常,只有拥有秘密信息的人才能够解扰(解密)消息。通过使用密码术,软件开发人员可以使数据保持机密。
认证:数据认证确保提供或访问敏感数据的任何人都是已授权方。通常,这涉及到用来证明您身份的某种口令或密钥。在理想化世界中,总可以确定地说出正与谁通信。从不必担心口令丢失或被窃或者要将密钥保密。有几种实际的方法来提供认证。拥有可以通过标准密码技术认证的秘钥是一种标准方法。我们将讨论解决认证问题的常见方法,包括数字签名系统。
完整性:仅当允许授权的团体能修改数据时才维护数据完整性。在网络上传送消息时,最终目标是确保当消息到达时,消息与最初发送的消息相同 -- 也就是说,在途中没有改变消息。如果已经改变了消息,则数据完整性通常通过检测来发挥作用。密码散列(不可逆变换)是某种允许我们保证数据完整性的校验和。还可以使用通用加密来确保数据完整性。
非否认:在通信中, 数据非否认涉及两个概念。首先,发送方应该可以证明预期的接受方实际获得了发送的消息。其次,接受方应该可以证明所谓的发送方实际发送了正在谈论的消息。实际上,实现绝对的非否认相当困难,因为很难证明没有泄露某人的密钥。
在理想化世界中,密码术将为这四个主要特征中的每一个提供完整、不可破的解决方案。但现实世界往往不完美。实际上,在一般使用的密码算法中常发现弱点。对优秀密码算法本身的错误使用也很常见。甚至还有一门破解密码算法的科学称为
密码分析学。我们将在稍后讨论对密码术实施的密码攻击。
虽然有这些麻烦,但理解是最重要的:合理应用密码术是强有力的手段。实际上,系统的密码部分是最难以直接攻击的系统部分。而系统软件的其它方面往往易受攻击。
为了演示该事实,让我们以汽车为示例。考虑您的汽车钥匙。由于汽车锁设计与实现方式的原因,某一特定钥匙将可以打开很多汽车。如果发现别的汽车与您的汽车类型相同且同年生产,那么可能会发现每 50 辆汽车中就有一辆可以用您的钥匙打开。本文作者之一十多岁时在摇滚音乐会的停车场验证了该理论,并在尝试了六辆汽车之后用他的钥匙成功打开一辆他人的丰田车。
但确实是这样。窃贼偷汽车时是带一些钥匙并尝试每一把钥匙直至打开汽车吗?不。还有简单得多的方法来打开车门。窃贼使用小薄片或其它类似工具来开锁,或者打碎窗户,或者可能用枪劫持并偷车,或者等待机会看哪辆车没锁或处于不安全状态。虽然钥匙和锁的保护组合看起来相当薄弱,但实际上确是足够的屏障,而那些坏家伙在攻击时通常使用其它方式。
密码术与之十分类似。首先,密码术中密钥的概念直接来自其硬件对等物的比喻 -- 没有密钥就无法加锁或解锁特定数据。在汽车示例中,攻击者有 50 分之一的机会使给定的钥匙工作,而在密码术中,通常有上十亿个可能的密钥(对于大多数密码算法类型,该数字通常是 2
n,其中,n 是密钥的位长)。然而,计算机可以自动以无法想象的速度尝试密钥。窃贼可能要花几分钟来尝试 50 把不同的汽车钥匙,而计算机只需一秒的一小部分(两亿万分之一)即可尝试 50 个密码密钥。幸运的是,很多情况下,128 位密钥足以强大来定义更多密钥,这比世界上所有计算机在合理时间内可能尝试的密钥多很多。
与汽车示例一样,攻击者通常不尝试直接的“试验每一把钥匙”方法,这主要是因为通常还有简单得多的攻击方法。安全性是一条链,一个环节损坏足以毁掉整个链。如果正确使用,密码术就是一个强壮的链。当然,仅一个环节不能保护整个链。换句话说,密码术本身不是安全性。
正确使用密码术的两种常见方法涉及到在加密操作过程前后两端攻击机器。也就是说,在加密数据之前或解密数据之后侵入机器并窃取明文通常要容易一些。既然有那么多的软件安全性缺点,那么对计算机的直接攻击通常是攻击者的最好办法。
密码术常见攻击
了解对手总是好的。理解可能出错的事情对帮助您评价要使用的任何密码算法很重要。
已知密文攻击。在这种攻击中,密码专家有一个称为
密文的消息加密版本(或者由同一种算法加密的多条消息)。操纵密文消息来尝试重新构造原始明文,并期望确定解密该消息(以及后续消息)所需的密码密钥。已知密文攻击的一个常见方式是蛮力攻击,该方法使用每一个可能的密钥来解密密文(回忆前面的汽车示例)。在尝试每一个密钥之后,检查密文是否为有效消息。如果使用了 2
64个可能的密钥来加密消息,则在找到实际密钥之前必须检查的密钥数预计为 2
63。那可是庞大的密钥数量。
已知明文攻击。在这种攻击中,密码专家既有消息的密文,又有该消息的相关明文,他要试图猜出将密文解密到已知明文的密码密钥。一旦知道该密钥,以后的消息可能也可以解密了。
选择明文攻击。这种类型的攻击与已知明文攻击类似,但是密码专家在加密特定明文(由分析人员选择)时可以监视。如果密码专家可以使用前一条消息的反馈来构造新消息,并看到这些消息如何加密,那么这就成为
适应性选择明文攻击。
选择密文攻击。在这种攻击中,密码专家可以用某种方式选择加密的消息,并查看其加密后的版本。目的是确定用于解密消息的密钥。
相关密钥攻击。在这种攻击中,密码专家使用有关不同密钥间关系的知识和其相关输出来猜测用于加密的密钥。
侧面攻击。有时可以从暗示正在使用的密钥的加密或解密的执行来推断看起来附带发生的信息。例如,如果在编码特定字符串所用时间和用于编码的密钥之间有可预知的关系,则密码专家也许能够极大减少蛮力攻击中的密钥数量。这种攻击通常需要已知的密文和选择的明文。
许多攻击实际上并不真是数学方法。相反,他们依赖邪恶的手段来获得密钥。这种例子包括偷窃和贿赂。偷窃和贿赂的确非常有效,而且通常十分易于实行。另一个例子是使用硬件设备来发出“猛烈”攻击。在这种攻击中,将复杂的硬件放置在将显示敏感数据的监视器几百英尺之内。监视器发出的辐射波提供许多信息,从而在显示明文时允许攻击者看到它。
常规建议
在本节中,我们将在谈到几个常见算法时将给出一些极其普遍和基于经验的建议。所有建议都附带警告:应用的密码术很棘手而且与环境相关。如果是至关重要的加密,则确保从具有真正密码经验的人士获得建议。
一条总的建议适用于密码的每一次使用。不幸的是,软件开发人员常常忘记它 --
永远不要使用自己的密码术。
某些人对用隐藏方法实现安全性很有信心。他们认为使算法保密就象依赖数学上的密码强度一样好。这真是错极了。对果断和有经验的密码分析专家来说,隐藏坏算法毫无优势可言。
最好的方法是使用已公布的、使用效果良好的且经过尝试和测试的算法,因为这种算法经历过多年考验。在攻击加扰的算法时通常需要攻击者考虑输入/输出对。算法被看成是黑箱。有了牢固的算法之后,知道确切的过程并不会泄露有关用于加扰明文的秘钥的任何信息。在大多数软件应用例子中,不管怎么说攻击者都会得到密码算法(内嵌在代码中)。使内嵌功能保密几乎不可能,而且这样做也不会使密码术得到增强。
拿 RC4 这个由 RSA Security 拥有的专有对称密码来说。RSA 将 RC4 作为商业秘密保护起来,并且只对许可证持有人发布。然而在 1994 年,有人对该算法进行了逆向工程,并匿名将其发布到因特网。实际的代码许可证持有人已验证了发布到因特网的算法是正确的(输入/输出兼容)RC4 版本。
在 RC4 的案例中,算法的公开泄露(将其发布给全世界)不会产生多大的安全性问题,因为算法被设计成假设在攻击者知道算法的情况下可以抵挡攻击。Ron Rivest(极受尊敬的密码员)创建了 RC4。相反,大多数自产的算法由业余密码员创建,很容易被密码专家击败。
事实上,我们所看到的大多数自产算法只是用某个常数对数据进行异或处理,然后对文本略微进行某些其它变换。这种类型的加密与不加密差不了多少。
有关密码术幼稚用法弊端的生动例子最近成为新闻界恐慌关注的焦点。在该问题案例中,Netscape 使用了非常简单的加扰算法来试图隐藏存储在客户机机器上的 POP3/IMAP 口令。
Netscape 加扰口令所用的加密算法异常脆弱。Tim Hollebeek(Reliable Software Technologies 副研究员)和 John Viega(本文章系列作者之一)可以只用八小时就推断出其算法。不用进行逆向工程。相反,使用铅笔和纸分析了仔细挑选的几百个口令。结果证实,算法是异或跟一个常量密钥的简单组合,并且还在猜谜杂志中发现了比那还要脆弱的替代密码。有关详细信息,请参阅
参考资料。
一旦知道密码,恢复存储在机器上的 POP3 或 IMAP 口令就轻而易举。攻击者既需要对受害人机器的物理访问,又需要有在其上运行代码的能力。移动代码攻击只需窃取其中带有加扰口令的一个文件副本。也就是说,只需要读权限。当前的 JavaScript 攻击可以做到这一点。
Reliable Software Technologies 在实验室里创建了一个行之有效的口令窃取攻击。一次成功的攻击允许坏家伙从远程机器下载和阅读受害人的电子邮件。由于仔细使用黑客技术不会留下太多明显线索,所以受害人电子邮件可以被悄悄窃取。唯一解决方法是关闭“记住口令”特性。
虽然窃取邮件本身就是非常严重的安全性和隐私问题,但是还有更危险的情况存在。最大的风险是人们对 POP3 和其它远程机器的登录使用同一口令(甚至可能是他们的 PGP 口令短语)。尤其是,很多人使用 IMAP 或 POP3 在家里访问与工作有关的电子邮件,而其邮件口令还是工作时使用的登录口令。事实上,登录帐户和邮件帐户常常相同。家庭计算机以不安全和易于渗透而闻名于世。恶意的攻击者可以读取存储在不安全的家庭计算机上的 POP3 口令(通常通过因特网),并用其登录到受害人雇员所运行的更安全的远程机器。然后,攻击者可以获得帐户控制权,读取敏感信息,攻击更具特权的帐户,并在公司网络内设置远程监控系统。Reliable Software Technologies 开发的代码也可以被用作有效工具,来实现险恶得多的梅丽莎病毒版本。
密码术出口法规
如果您是美国居民,可能会注意到:以前,美国联邦政府将密码术看成是军需品。在很多情况下,没有有效的出口许可证而在美国以外分发包含任何合理密码术都被认为是违法的。您不能卖它,也不能让人们从 Web 站点下载。通常给予允许的唯一例外是用于大型金融机构的情况。
密码术法规旨在保护国家安全性,防止恐怖分子和毒品走私贩使用强大的密码术。然而,在美国试图保护他们的算法时,这个星球上的其它国家早已有了相同的算法。就如他们在田纳西州所说的,没有马却关闭马厩门豪无意义?愚蠢的密码术法规只是伤害了美国的商业利益,因为美国公司无法将其具有强大密码术的产品卖给其它国家的人。
现在,无需特殊许可即可出口 56 位或更低强度的密码术。比 56 位强大的密码术还需要出口许可证。当您阅读本文时,法规可能已经变更,因此此处所讲的仅供参考。我们所能做的最多是建议如果要出口具有加密功能的软件,要向律师咨询。美国之外的其它国家也有密码术出口限制,甚至有一些还有进口限制。最好查看一下当地法规。
有一些妙法可规避强密码术限制。某些公司做的工作很合理。他们不出口密码术。相反,他们进口。他们或者在本国之外开发密码软件,或者让某人在国外将密码术添加到其软件。这种解决方案可能不适合每个人。更实际的方法是将软件设计成不带密码术工作,但可以与现有可免费获得的密码术包(当然美国以外的人们可以获得该包)互操作。人们可以下载密码包然后自己将其放入应用程序。这种方法相当普遍,某些包甚至还提供详细的指导信息,告诉人们在分发软件时如何下载和安装合适的密码包。
传统密码术
有几种不同类型的密码术可供您在应用程序中使用。使用哪一种取决于您的需要。当然在一个应用程序中使用多种类型的密码术是适当的。从现在开始我们将讨论在计算机出现之前密码术是什么样的。别忘了,对您来说最好别使用如下所示的传统算法,而要使用更现代的密码!(问一下 Netscape 就知道了)。在后两部分,将演示更现代的密码术。
几千年来,密码术一直被用于保护通过不安全渠道发送的军事和外交秘密。所有传统密码系统都通过在消息发送之前达成一个密码(还可能是密钥)共识来工作。现代密码员认为公共密码是最好的使用方式。以前,密码必须保留所有通信可能会泄露的秘密或安全性。如果使用任何类型的密钥,它远不及如今现代方法中的密钥那样强大。
在本世纪之前,大多数密码系统都基于字符替换或字符换位(称为
替换密码和
换位密码)。最著名的传统密码可能就是恺撒密码,通常认为这是最先发明的加密算法之一。在恺撒密码中,通过将每个字母按照字母表向下旋转固定次数来将明文消息转换成密文。当使用一个字符的旋转时,将把字母 "A" 加密成 "B",把 "B" 加密成 "C",把 "Z" 加密成 "A"。例如,旋转一个字符之后,字符串 "HELLO WORLD" 将变成 "IFMMP XPSME"。在该算法中,有 25 个密钥(当然是在使用英文的情况下)可以确定每个字符旋转的字母数。如果攻击者知道使用的密码,那么尝试 25 个可能的解码来查找密钥并不会花多长时间。大多数情况下,只有一种解码有意义。
恺撒密码是
替换密码的一个特殊情况。最简单的替换密码是字母表上 26 个字母的置换。下面是一个替换密码示例:
| 输入 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | | 输出 | Q | W | E | R | T | Y | U | I | O | P | A | S | D | F | G | H | J | K | L | Z | X | C | V | B | N | M |
要加密消息,首先在第一行查询明文中的每个字符,然后将其用第二行中的字母替换。例如,将把 "HELLO WORLD" 加密成 "ITSSG VGKSR"。要恢复该消息的明文,首先在第二行查询密文字母,然后将其用第一行的字母替换。
假设可以安全分发此处显示的密码。另外假设可能的攻击者猜出使用的是直接替换密码,但不知道确切的置换。26 个字母的字母表有 2
88到 2
89个不同的置换。在没有计算机的社会中,很明显,蛮力攻击不可行。尽管如此,如果有足够的密文,这样的密码往往不难攻破。关键是计算密文中每个字母出现的实例。既然 E 是英语中最常用的字母,那么给定一个足够大的密文,该文本中最常出现的字母很可能就是 E。如果不是,那可能是 A、I 或 O。传统密码专家只用十几个密码字母就能很快地进行这种统计攻击。
替换密码可以随意变得更复杂,希望这可以从密文中除去可导致简单分析的元素。例如,可以使用这样的密码:同一密文根据上下文不同而代表不同明文字母,以使对密文的统计分析难以进行。可以使一个密文位映射成多个明文位的组合。还可以“级联”加密,以便一个位的加密取决于前一位的解密。例如,请注意在前一例中,"L" 在明文中出现了三次,而相应的密文字母 "S" 也出现了三次。让我们修改算法,以便将明文字母旋转 n 位,然后加密旋转后的位。n 的值取决于密文中的前一字母。如果前面没有字母,则不旋转。否则,如果密文的前一字母是 "A",则在进行表查询之前先旋转一个位置。如果前一字母是 "Y",则旋转 25 个位置。
让我们在字符串 "HELLO WORLD" 上试一下新密码。首先加密字母 "H"。既然前面没有加密文,就根据我们的表来转换它,因此将其加密成 "I"。现在考虑 "E"。既然它前面的加密文本字母是 "I",将 "E" 旋转九个位置,得到 "N"。然后根据我们的表将字母 "N" 转换成 "F"。目前为止,密文是 "IF"。对每个字母遵循该步骤,就得到 "IFKCK YFBFP"。如果知道密码,反转这个过程不太困难。
字母 "F" 在密文中出现了三次,但是每一次都映射成明文中完全不同的字母(E、O 和 L)。字母 "K" 也出现两次,分别映射成 "L" 和 "D"。这种方案使对密文进行分析攻击的难度显著增加。
替换是传统密码中的主要原始方法,但是置换字符的实际位置是另一种原始方法。大多数现代密码算法构建在这些相同的基本准则之上。它们的区别在于:现代算法执行的替换和换位要多得多。当然,传统算法要由手工应用。即使是相当简单的密码和相当短的消息,加扰和解扰一条消息也很费时间。然后出现了计算机(在计算机的首要使用中密表将码术用得很多)。计算机可以使用经过大量置换次序处理的更复杂算法,同时加密和解密速度还比人工快许多。以那种方式,现代密码远远超出了传统密码。
下一部分,将讨论现代密码术的本质,即,
对称(秘钥)密码术和
公钥密码术。
参考资料
作者简介  | |  |
Gary McGraw是Reliable Software Technologies企业技术部的副总裁,该公司位于美国弗吉尼亚的杜勒斯 (Dulles)。他在咨询服务和研究部门工作,帮助决定技术研究和开发方向。McGraw 在 Reliable Software Technologies 公司从一个研究科学家做起,从事软件工程和计算机安全性方面的研究。他拥有印第安那大学 (Indiana University) 的认知科学和计算机科学双博士学位,弗吉尼亚大学 (Virginia University) 的哲学学士学位。他为技术刊物撰写了超过 40 篇经过同行审查的文章,担任过主要的电子贸易供应商,包括 Visa 和 Federal Reserve 的顾问职务,并在空军研究实验室、DARPA、国家科学基金会,以及 NIST 的高级技术项目授权下担任其主要调查研究员。
McGraw 是在移动代码安全性方面的著名权威人士,和普林斯顿大学的 Ed Felten 教授一起合著了 "Java Security: Hostile Applets, Holes, & Antidotes" (Wiley, 1996) 和 "Securing Java: Getting down to business with mobile code" (Wiley, 1999)。McGraw 和 RST 联合创始人之一及首席科学家 Jeffrey Voas 博士一起著作了 "Software Fault Injection: Inoculating Programs Against Errors" (Wiley, 1998)。McGraw 定期地为流行的贸易出版物供稿,并常在国家级新闻稿件中援引。
|
 | |  |
John Viega是一名高级副研究员,Software Security Group 的创始人之一,并担任 Reliable Software Technologies 的高级顾问。他是由 DARPA 赞助的开发标准编程语言安全性扩展的主要调查研究员。John 已撰写了超过 30 篇涉及软件安全性和测试领域的技术文章。他负责在主要网络和电子贸易产品中查找一些众所周知的安全性薄弱环节,包括最近在 Netscape 安全性中的缺陷。他还是开放源码软件社区的主要成员,编写过有关 Mailman、GNU Mailing List Manager 和最近的 ITS4(一种在 C 和 C++ 代码中查找安全性薄弱环节的工具)等文章。Viega 拥有弗吉尼亚大学 (University of Virginia) 的计算机科学硕士学位。
|
对本文的评价
|