原文地址http://www.ibm.com/developerworks/cn/java/jw-0428-security/
在最近的几十年内,计算模型发生了巨大的变化,由于这些变化,出现了对大规模电子商务与电子交易系统应用程序安全的更大需求,这正如最近对几个受欢迎站点的大量拒绝服务 (DoS) 攻击所表明的那样。尤其是对于 Java 团体,随着 Java 作为因特网编程的事实上的标准平台出现,安全移动 Java 代码的能力已成为基本要求。
本文是系列文章中的第一篇,讨论计算机安全和密码学的一般概念。虽然可移动代码并不是一个革命性的概念,但是 Java 和因特网给计算机安全带来了一些不同寻常的挑战。Java 体系结构的演化及其对安全的影响、不同的安全 API 和工具软件以及 applet 安全,等等,将在随后的文章中讨论。
此安全性论文系列并不打算提供计算机安全问题的综合指南。计算机安全是一个多层面的问题,它涉及若干学科、部门和文化。技术投资后,接着就应该着手培训、严格的策略强制执行和总体安全策略的定期审查。
注:有关算法进展的详细信息,请参阅专题“ 二十一世纪的加密算法”;有关密钥长度在安全性中的重要性的讨论,请参阅专题“ 密钥的长度是否重要?”。
什么是计算机安全?
要从总体上理解什么是计算机安全,有必要考虑一下安全在日常生活中意味着什么。我们将看到,日常生活中的一般安全规则同样适用于计算机安全。
计算机安全的局限性
有没有绝对计算机安全这样的事情?一句话,没有这样的事情。术语安全系统是一个不恰当的名称,因为它暗示了系统要么是安全的,要么是不安全的。安全实际上是一种平衡。如果提供的资源是无限的,则任何形式的安全都能遭到破坏。尽管攻击者可用来实施攻击的资源越来越多,但在现实世界中,这些资源仍然是有限的。考虑到这一点,我们应该这样来设计所有系统:让攻击者为破坏这些系统所付出的,远远大于破坏之后他们所能得到的。
端到端的安全
什么是端到端的安全?在一个多层系统中,每一层都应该有其自身的安全,并且与其他层协调一致。为汇集在一起的不同系统和中间件设计安全,是一个相当大的挑战。简单地说,系统安全的程度仅相当于最弱的一环的安全程度;除非您按端到端的观点考虑安全,否则安全随时可以遭到破坏。
简单性
一个复杂的安全设计会起作用吗?乍看起来,制止未授权用户访问系统的最佳方法也许是,设计一个非常复杂的安全方案,但事实并非如此。不仅设计复杂的安全系统的高成本使人不敢问津,而且,要是这种安全系统太复杂了,恐怕连合法用户也难以进入。另一方面,简单系统更容易理解,也更容易分析。
好的系统设计需要安全
有可能对安全进行翻新吗?答案是,这几乎是不可能的。在很多情况下,翻新安全而不必重新设计系统的实质性部分,可能是不现实的。在几乎所有的情况下,翻新的成本非常昂贵。因此,安全从来不应是事后考虑的事情 -- 从一开始它就必须是系统设计的不可分割的一部分。
计算机安全的基础知识
了解这样一些内容是有用的:计算机安全的防御对象、相应的防御机制,以及与计算机安全有关的不同术语。
威胁
威胁 -- 对计算机安全的攻击 -- 大致可以分为以下几类:
- 机密性攻击:利用加密算法中的弱点或以其他方式,试图窃取机密信息。
- 完整性攻击:出于自私或恶意而试图修改信息。应该注意的是,完整性攻击也可以是偶然的。
- 可用性攻击:试图中断系统的正常运行。可用性攻击又称为拒绝服务 (DoS) 攻击,后者是最近流行的术语。
几种攻击归属于上面提到的一个或几个类别。示例包括:
- 暴力攻击通常指搜索每一把钥匙,直到用正确的那一把打开门为止。尽管这似乎是一项代价昂贵的操作,但实际上,通过使用专门的工具对搜索进行仔细安排,是可能的。
- 特洛伊木马攻击以敌方不易察觉的方式插入一个内线。计算机病毒就是常见的特洛伊木马攻击的例子。
- 转接攻击 (person-in-the-middle attack) 在双方不知道的情况下,中途截取他们的通讯信息,而双方以为他们在正常通讯。
其他的攻击包括:生日攻击、字典攻击、会合攻击 (meet-in-the-middle attack) 等。(更全面的讨论,请参阅 参考资料中 Bruce Schneier 的 Applied Cryptography。)
防护物
为抵御对安全的威胁,有各种各样的保护机制。在历史上,防御机制曾经包括设置某种“围墙”或“边界”,通常称为周边防御 (perimeter defense)。
防火墙,周边防御的一个相当成功的示例,将内部(专用)网络与外部(公用)网络分隔开,并为公司策略提供中央控制点。然而,防火墙日益允许各种精选形式的通讯 -- 例如 HTTP -- 穿过它。
虚拟专用网络 (VPN),尽管仍然使用共享网络,但它提供的安全级别与专用网络相同,是另一个防护物示例。
密码学
密码学及其相关领域密码分析学,自身与加密和解密信息的算法设计及分析有关。在下面的几节中,我们将讨论密码学与安全之间极其重要的关系。
机密性
机密性是保护数据免受未授权的一个或多个用户访问的方法。简单地说,就是只有预定的消息接收人才能够弄懂这一消息。
如果您正在与他人交换敏感信息,您希望绝对确保只有预定的消息接收人才可以弄懂此消息,如果落入非预定的人手中,此消息实际上将变成无用的东西。机密性是用某种形式的加密技术来实现的。
认证
认证过程确认用户的身份。用户可以是一个软件实体,也可以是一个人。委托人是其身份已被验证的一方,与委托人相关联的是一组凭证。通常,认证根据一些仅用户和认证人知道的机密信息 -- 例如口令 -- 来确认身份。除了口令以外,更复杂的安全方案还将诸如智能卡或生物统计法(指纹、视网膜扫描,等等)之类的高级技术用于认证。
一旦建立了认证,在实施中对用户(或者更一般的说,委托人)的访问是访问控制机制控制的。
Kerberos -- 基于密钥和加密 -- 展示了一种早期认证技术。这种技术使用时间戳 -- 在一个规定的时段内会话保持有效 -- 来实现这一点。为了正常工作,Kerberos 最根本的一点是,假定分布式系统中的时钟是同步的。
公用密钥基础结构 (PKI),代表一种更为普遍的认证解决方案,将在下面的几节中讨论。
Java Authentication and Authorization Service (JAAS) 框架,以基于用户的认证和访问控制功能补充 Java2 平台。JAAS 是 Java 2 Software Development Kit,v 1.3 的标准扩展。
完整性
比如说您发送一张电子支票。当银行最终收到该支票时,它需要弄清楚付款金额有没有被篡改,这就是称为完整性的安全概念。
不可否认
在上述的电子支票示例中,如果您确实发送了该支票,就应该没有办法再否认它。不可否认提供不可否认的行为证据,如给接收人的数据的原始证明或给发送人的数据收据。
审计和日志
保存已授予或已拒绝的资源访问的记录,可能有助于日后的审计工作。就此目的而言,审计和日志对于防止非法入侵或事后对非法入侵进行分析,是大有用处的。
策略和访问控制
安全策略着重控制对保护数据的访问,安全执行机制应该足够灵活以执行策略,这一点至关重要。这称为保持策略与机制相分离。尽管作出该决策的依据可能是,按照委托人身份来授权访问某一资源,但是,根据角色来管理访问控制通常更为容易。每个委托人被映射到唯一的一个角色,以达到控制访问的目的。通常这样来实现:用一个列表或矩阵,列举不同的用户/角色所拥有的对不同保护资源的访问权。
Java 2 Platform,Enterprise Edition (J2EE) 使用基于角色的认证来执行其策略。考虑到这一点,在 J2EE 中,业务逻辑的开发人员根据角色来限制对特定功能的访问。
密码学:保密书写的科学
虽然密码学和计算机安全是两个截然不同的主题,但是计算机安全在很多方面都依赖于密码学。
Java.security与几个核心包一起提供了一些 Java 的加密功能。Javax.crypto是主要的包,它的某些功能部件受出口控制法的控制。此外,javax.net.ssl包在必要时可用来创建安全套接字传递机密信息。
下一步,让我们了解一些与密码学有关的概念。
密码分析学
密码分析学,与密码学正好相反,是解码或攻击秘密编码信息而无须访问密钥的艺术。密码分析学已经使用理论性攻击发现了许多算法中的安全漏洞,并导致了算法的废弃或重大修改。密码分析学在分析和验证算法,使算法更加安全方面,起着关键性作用。
密码学算法
有几种算法可以加密信息。一种简单的算法可能要将消息的字符轮换 13 个位置 -- 称为 rot13。虽然 rot13 是不安全的(因为原始消息很容易解密),但是它仍然普遍用于虽不安全但毕竟是已加密了的消息传送。
如果以 Kerckhoff在十九世纪所做的工作为基础,则密码系统的安全应该完全基于密钥的保密,而不是基于算法的保密。密钥,再加上经过充分测试和分析的算法,可用密码学方法生成安全的系统。相应地,许多广泛流行的算法可用于公众审查。对许多算法所做的密码分析学工作导致了对算法的若干修改,从而使它们的功能更强大。
注:有关设计下一代加密标准的过程的信息,请参阅第一个 专题。
单向散列函数
单向散列函数 H(M),对一则任意长度的消息进行处理,并返回一个具有固定长度 m的散列值 h:
这一算法的安全源于其单向性,而不是其内部工作方式的保密性。更严格地说, H(M)具有以下属性:
- 给定 M,很容易计算出 h
- 给定 h,很难计算出满足 H(M) = h的 M
- 给定 M,很难找到一则消息 M',使得 H(M) = H(M')
散列法是数字签名的基本部分,将在下面讨论。 RSA 的 Ron Rivest 设计了 MD4(消息摘要)和 MD5(RSA 是一家安全公司的名称,它由该公司创始人 Ron Rivest、Adi Shamir 和 Leonard Adleman 的姓氏首字母组成。MD4 和 MD5 产生一个 128 位散列。 SHA(安全散列法算法),由 National Institute of Standards and Technology (NIST) 与 National Security Agency (NSA) 联合设计,它产生一个 160 位散列,用于数字签名算法 (DSA)。 SHA-1,在某些文献中简称为 SHA,是 1994 年发表的 SHA 的修订版。SHA 和 SHA-1 都是安全散列标准 (SHS) 的一部分,与 MD4 函数系列有共同之处。MD4、MD5 和 SHA 是单向散列函数的一些示例。
作为一个例子,根据 MD5 算法为外观类似的消息生成了下面的 128 位散列。
表 1. 使用 MD5 的散列值
原始消息
|
散列值(用十六进制表示)
|
a quick brown fox jumped over a lazy dog
|
13b5eeb338c2318b790f2ebccb91756f
|
a quick blue fox jumped over a lazy dog
|
32c63351ac1c7070ab0f7d5e017dbcea
|
a quick brown dog jumped over a lazy fox
|
a4c3b4cd38ade6b5e2e101d879a966f5
|
对于任意长度的消息,此算法都将生成一个代表该消息的固定长度的散列。从表 1 可以清楚地看出,即使稍微修改消息,也会更改其散列。要找出散列值相同的一个替换消息,将是一件耗费时间的事情。
到目前为止,我们已经讨论了不使用密钥的单向函数。另一方面,消息认证代码 (MAC) 是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息。 HMAC(用于消息认证的密钥散列法)就是这种函数的一个例子。
对称密码
对称密码,在与密钥联合应用时,将明文转换为密文。密码也可以使用相同的密钥将密文恢复为明文。所谓对称性,即指加密和解密使用完全相同的密钥。加密和解密有两个相关的函数,如下所示:
Ek(M) = C,其中
M 是明文, C是密文, k是密钥
Dk(C) = M,其中
C、M和k的意义同上
|
它们具有基本的属性:D k(E k(M)) =M
给定一个设计良好的算法,则过程的安全就在于密钥的保密。因此,对称密码的主要挑战在于密钥的分布形式 -- 通讯双方如何共享同一密钥?不同的是,非对称密码则不使用同一密钥。相反,它们依赖一个广泛可用的、自由分布的公用密钥。
使用专用密钥的加密通常比使用公用密钥的加密速度快。在一个混合的密码系统中,用于会话的专用密钥称为会话密钥,是使用公用密钥建立的,通讯双方将会话密钥用于会话的其余部分。这是一种形式的密钥交换。其他形式的密钥交换使用更安全的通道来交换专用密钥。
可以将对称密码分类为流密码或块密码。流密码对位流或字节流进行操作,而块密码则对一组位进行操作。密文中的本质区别是,如果使用块密码的同一密钥进行加密,则相同的明文块将加密为相同的密文块;而在使用流密码时,则每次加密时都将明文块加密为不同的密文块。
大多数块算法都符合 Feistel 网络属性,这意味着用于加密和解密的算法是相同的,仅在密钥的应用方面存在一些差异。
有几种操作模式。模式可以增强加密,还可以修改对称密码的特征。例如,通过使用适当的模式,可以使一个块密码的行为与一个流密码相似。下面列出的是几个重要的模式:
- 电子食谱模式 (ECB)
- 密码块链接 (CBC)
- 密码反馈模式 (CFB)
- 输出反馈模式 (OFB)
有几种块密码,其中包括数据加密标准 (DES)。DES 将由高级加密标准(AES) 代替(请参阅 专题 ,“AES:二十一世纪的加密算法”)。同时,Triple DES(3DES 或 DESede),是对 DES 的改进,它在采用 AES 之前替代 DES。在 DESede 中,加密过程是使用不同的密钥依次进行编码、解码和编码的处理,有效地增大了密钥的长度。
非对称密码
与加密和解密都使用相同密钥的对称密码不同,非对称密码以如下方式使用不同的密钥:
Ek1(M) = C,其中
k1 是加密密钥
Dk2(C) = M,其中
k2 是解密密钥
|
非对称密码具有以下的基本属性:
在非对称密码中,通讯双方不必共享同一密钥。然而,密钥 k1和 k2在数学上是相关的,以便使加密和解密处理相关联。
公用密钥和专用密钥
非对称密钥密码又称为公用密钥密码学,因为它们涉及公用密钥这一概念。公用密钥是可自由使用的,而专用密钥是一个秘密。在一个用户网络中,每个用户都有其自己的公用密钥,这些密钥在一个通常可访问的目录中发布。
在二十世纪七十年代中期,Whitfield Diffie 和 Martin Hellman 一起,Ralph Merkle 一个人,分别引入了公用密钥密码学。公用密钥算法的安全基于以下过程的难度:在不知道密钥的情况下,从密文推断出明文,以及从公用密钥推断出专用密钥。
了解下面这一点是很重要的:在大多数文献中对公用密钥和专用密钥的讨论可能是模糊不清的,因为许多文章看起来是将相同的密钥用于加密和解密,但是在讨论中隐含了这样的事实:它们所说的密钥,一个是专用密钥,另一个是公用密钥。
要注意的另一点是,在使用多个算法时,要求使用多个密钥,因为密钥对算法来说是唯一的。
下面将讨论的数字签名和证书均依赖公用密钥密码学。
数字签名
数字签名,很像实际生活中的签名,提供发送人可靠性和消息完整性的证明。数字签名可用于“不可否认” -- 发送人无法否认他(或她)已经签名。数字签名要成功就必须不可伪造并不可重用,而且已签名的文档必须是不可修改的。
基本的数字签名协议是:
- 发送人用他/她的专用密钥加密文档,并隐式地在文档上签名
- 消息发出
- 接收人用发送人的公用密钥解密该文档,从而验证该签名
由于在大文档上签名很费时,因此通常只在消息的散列上签名。单向散列和数字签名算法被公认为是先验的。原始消息与签名一起发送。接收人用发送人的公用密钥解密散列,并将它与由收到的消息生成的散列相对照,来验证签名。下面的图 1 说明签名的生成和验证过程。该方案还有一个好处,即将文档和签名分开。
图 1. 数字签名
请注意,消息使用散列算法生成一个固定长度的散列,然后加密该散列以生成签名。这些签名有时称为数字指纹,因为它们唯一地代表原始消息。
使用数字签名并不保证机密性,因为消息是作为明文发送的。为了进一步保证机密性,而不是发送明文消息,可以用发送人的专用密钥对它进行加密,此过程如图 2 所示。
图 2. 加密的数字签名
数字签名有几种算法,如 ElGamal 签名、RSA 或数字签名算法 (DSA)。ElGamal 和 RSA 算法都可以用于加密和数字签名。不同的是,DSA 是数字签名标准 (DSS) 的一部分,则只能用于数字签名,不能用于加密。如果希望加密,则必须将其他的加密算法与 DSA 联合使用。
下面的表 2 简明地汇总了目前所讨论过的所有不同加密算法的各种特征,并对每一种算法提供了一些示例。
表 2. 加密算法总结
加密算法
|
简要说明
|
安全属性
|
问题
|
示例
|
安全属性
|
单向散列函数
|
生成长度固定的唯一签名
|
算法的单向性
|
签名冲突
|
SHA、MD4、MD5
|
|
消息认证代码 (MAC)
|
使用密钥的单向函数
|
算法的单向性
|
签名冲突
|
HMAC
|
认证
|
对称密码
|
用同一密钥加密和解密
|
密钥长度和算法
|
密钥分布
|
DES
|
认证、完整性、机密性
|
非对称密码(公用密钥密码学)
|
加密和解密使用不同的(公用的和专用的)密钥。很容易获得公用密钥。
|
密钥长度、算法,以及从公用密钥推断专用密钥的难度。
|
信任问题
|
RSA、ElGamal
|
认证、完整性
|
数字签名
|
为认证而生成散列消息,并用发送人的专用密钥加密
|
单向性和密钥长度
|
无保密性
|
DSA、RSA
|
认证、完整性
|
带加密的数字签名
|
消息签名、并用接收人的公用密钥加密
|
签名、加密算法和密钥长度
|
信任问题
|
数字签名和密码的组合
|
认证、完整性和机密性
|
证书
由于数字签名依赖于公用密钥的完整性,那么验证人如何确保他们获得的公用密钥不是来自某个冒名顶替者呢?而且,在数字签名认证发送人的同时,接收人如何能够确保发送人值得信任呢?
这些问题的解决方案就是证书。由共同信任的第三方或证书管理机构 (CA) 颁发证书。CA 不仅有公用密钥,还有用户的其他信息。证书含有一个有效期。颁发机构用它的专用密钥在证书上签名。该过程隐含一个假定,即 CA 的公用密钥是广泛可用的和真实的。
公用密钥证书以 X.509标准为基础。CA 的一些示例包括 Verisign、Thawte (现在由 VeriSign 拥有)和 Entrust。在 Java 中,javax.security.cert程序包提供证书支持。
公用密钥的基础结构
较新的公用密钥基础结构 (PKI) 因来源不同而有几种含义。一种观点认为 PKI 是指信任层次结构和公用密钥证书,而另一种观点则认为它还包括加密和数字签名服务。PKI 还解决了几个与密钥有关的问题,包括密钥的注册、撤消、选择、恢复,等等。
</script>