第三部分 分布式系统第10章 分布式系统安全
如果存在一个单一的策略,一个单一的系统管理,一个单一的安全执行系统,则计算机安全就容易实现。但是,正如你已经注意到的,即使在相当有利的环境下,直截了当地实现计算机安全也是不实际的。当然,集中式的安全要比分布式的情况好得多。
在这一章里,我们使用“分布式系统”(异构或者联合系统)作为通过网络连接的计算机集合(collection,集合,聚集;收集,汇集;【ST】类集)的模型。分布式系统的各个组成部分可能分布在不同的组织机构里,在不同的职权管理下,且使用不同的安全策略进行管理。在一个真正的分布式系统中,用户并不想知道服务的位置,也不想知道他们正在使用的对象所在的地点。
本章内容
·了解在分布式系统中发生的基本安全问题。
·说明在过去几年来分布式系统安全发生的变化,未来要达到的目标。
·考察在分布式系统的哪一个系统层次上实现安全机制最合适。
·理解当前引入的分布式系统安全机制的承诺和缺陷。
10.1 概 述无论何时,你改变了计算机的运行环境,都必须对已经建立的安全机制的适用性进行重新评估。当你把计算机从集中式系统移植到一个分布式系统的时候,对于安全来说,存在一个很明显的冲击。当检查分布式系统安全的时候,有必要理解所有的在集中式系统中内含的安全假设,这些假设是实现集中式系统安全的基础。
为了了解这些改变会怎样影响你,让我们看一下通过口令的身份认证。当用户在一个终端上工作,并且这个终端固定地连接到一台主机上的时候,口令是非常有用的。在这种情况下,你可以有正当的理由相信,在终端和主机之间的连接是安全的,并且不可能窃听口令,更改或插入消息,或者被别人接管一次会话。而在分布式系统中,对于通信链路安全这样基本的假设几乎是不成立的。然而,口令认证仍然是分布式系统最常用的认证机制。
十几年前,分布式系统安全主要关注的是认证机制。今天,你可以用防火墙来保护你的内部网络的周边环境,用安全体系来保护对分布式对象的访问。从分布式系统的特征来看,一些更深一层的问题出现了:对用户权限的授予或者撤销、信任机制、安全性和其他的分布式系统的特性(如可靠性和可用性)之间的相互作用。为了综述分布式系统安全的现状,我们从研究分布式系统中的一般安全策略和安全实施开始。
10.1.1 安全策略在分布式系统中,当用户访问一个对象的时候,他们不需要登录到被访问对象所在的结点上。这就出现了一些问题:
·你怎样认证用户?
·什么是访问控制判决的基础?
为了回答这两个问题,可以有三种选择。用户认证和特殊访问控制可以基于:
·用户身份;
·用户操作来源的网络地址;
·用户正在使用的分布式服务,即访问操作。
Unix在像ftp或者telnet远程访问服务中采取了第一种选择。ftp程序在两个Unix系统之间传输文件。telnet程序创建一个远程的虚拟终端。这两种程序都提示用户输入用户名和口令。rlogin程序的工作过程类似于telnet;它自动传送当前用户的用户名,仅仅提示用户输入口令。在所有这三种情况下,可以使用正常的Unix访问控制,但是网络通信引入了新的脆弱性。在这一章,我们将讨论一些更加有效的认证方案。
如果访问控制的决策是基于用户身份的,那么用户的身份和访问权限是怎样联系在一起传播呢?在Unix环境下,你必须决定对于用户(比如,root)的特权可以做什么,以及来自远程结点的程序(例如,一个SUID程序)的特权和所有权可以做什么?在多级安全的情况下,你可能发现在分布式系统的结点之间,这些标签方案表示的意思是不相同的。因此橙皮书(Orange Book)和红皮书(Red Book)给出了在结点之间数据传输的策略,这将维护安全标签的不同粒度(granularities)。
在有些糟糕的情况下,分布式系统中的访问操作可能呈现出新的含义(meaning)。想象如下一种情况,当你发送一个读远程服务器上数据的请求时,服务器将把数据写到连接到你的系统的输出通道上。服务器应该用哪种访问规则,哪些用来读访问或者哪些用来写访问?
你可以决定来自于系统中的某些结点的用户不必再次进行认证。在Unix中,你可以在(rhosts文件中详细说明这些可信任的主机。你也可以定义可信任用户,他们不必提供口令且允许使用rsh(远程shell)命令。这些特点提供了一个非常简单的单站式签到(single sign on)系统,但是它严酷地依赖于消息认证的质量和初始化时允许用户进入一个可信任域的主体认证,如同8.7.1节示例说明的那样。在Windows NT中,这种信任关系提供了一种更完善的方式,它使得在可信任域中的用户可以访问信任域中的任何资源(见7.5.4节)。
10.1.2 授权在分布式系统中,受控调用照字面上的意义(literally,字面上(简直))呈现出新的特性(dimension,尺寸(量纲,维数))。一个用户可以在本地结点登录,然后在远程结点上执行一个程序。为了获得对远程结点上资源的访问,这个程序将需要相关的访问权限。在典型情况下(typically,代表性地,作为特色地),程序将被赋予(endow)用户的访问权限,然后以这个权限在远程结点上运行。这个过程称为授权(delegation,授权;代理)。
在远程结点上的程序,现在以用户授予的所有访问权限运行。在一个分布式系统中,用户对于把他所有的权限给予到一个没有什么控制权的结点上,可能会感觉到不太舒服。如果远程结点上存在弱保护,攻击者就可能攫取用户的访问权限,并且为了一些非法的目的使用这些权限。因此,你可能更喜欢这样的系统,在系统中用户自己可以控制那种他们授予的权限,责任机制能够用来鉴别访问权限的授权使用。
对于流行的服务来说,你可以创建代理用户(proxy user)来处理远程服务请求。你首先检查远程用户是否被授予了(entitle,给与权利(命名),(常与to连用)授权)运行这种服务的权限,然后让代理执行请求的动作,且用代理自己的权限而不是远程用户授予的权限运行。
10.1.3 安全执行一旦你解决(sort out)了你的策略,你就已经决定了如何执行他们。必须回答下面的显而易见的问题:
·在哪儿认证一个用户?
·在哪儿做访问控制的决策?
这些“哪儿”可以用两种方式来解释。你可以考虑在1.4.4节提到的第五个设计决策;决定是否执行集中安全或者局部安全。在第一种情况下,你可以采用像Kerberos(10.2.2节)一样的认证服务器(authentication servers)和通行票授予服务器(ticket-granting servers),或者安装一个防火墙来控制对内部网络的访问(13.4节)。在第二种方式中,各个结点的操作系统负责安全执行,比如数字设备公司(DEC)的分布式系统安全体系结构(10.2.2节)。另外一个可选方案是,你可以从1.4.2节提出的第二种设计决策中获得启示,然后决定在最合适的层次上实现分布式系统的安全。我们在10.4节中讨论这个问题。
10.2 认 证不经过任何保护的口令在网络上传输是一个非常明显的脆弱性。发掘这种脆弱性可以容易地自动实现。口令嗅探器sniffers是一个网络程序,它可以侦听通信流,从中提取出包含口令的包和其他与安全相关的信息。因此。作为走向分布式系统安全的第一步,我们应该考察更好的认证方案。下面介绍的这两种方案是集中安全实施方案和局部安全实施方案的实例。
10.2.1 Kerberos认证
Kerberos系统是美国麻省理工学院MIT在二十世纪80年代的雅典娜(Athena)项目中开发出来的。雅典娜为MIT的校园学生提供了计算资源,但是它的范围已经超出了MIT的校园范围,包括了一些附加的管理功能,比如财会功能。由Kerberos声明的危险和威胁,如在文献【103】中描述的,有:
这种环境对敏感数据或者高度风险(risk,危险;风险)的操作是不适合的,如银行事务处理、机密的政府数据、学生成绩、对危险实验的控制等等。这些危险主要是不能控制非授权的当事人使用资源,对系统或用户资源完整性的破坏,大规模地侵犯个人隐私,比如偶然地完全浏览个人文件。
因此Kerberos在其后被广泛地接受了。有几个工业标准采用了Kerberos作为分布式系统的认证系统,值得注意地是作为RFC 1510[80] 发布。Kerberos在分布式系统中认证需要服务的客户(client)。认证是围绕通行票(ticket,票(标签,证明书);票证,入场券)和集中式安全服务器的概念建立的。术语“主体”(“principals”)代表客户(用户)和参与网络通信的服务器。
·Kerberos 认证服务器(KAS):认证登录的主体,然后发给其通行票。在一般情况下,通行票只在一次登录会话中有效,可以让主体从通行票授予服务器获得其他的通行票。认证服务器有时也被称为“密钥分发中心”(KDC)。
·通行票授予服务器(TGSs):向主体发布通行票,用来访问要求认证的网络服务。
Kerberos来自于Needham-Schroeder密钥交换协议(12.3.2节)。像DES这样的对称密码系统常常被用来加密数据。用户名和口令用来认证用户,但是口令不能通过网络进行传输。因特网RFC 1510给出了Kerberos版本5的一个详细规范说明,包括当一个协议运行不能继续时发出的出错信息等。下面的简单描述省略了在Kerberos消息中的一些数据域,并且仅仅处理了协议运行成功地完成时的情况。将使用下面列出的约定:
, 用户A的秘密(cryptographic,【修】密码,加密)密钥,它是从用户A的口令通过单向算法计算得到的;KAS有一个的备份
, 由TGS和KAS共享的秘密密钥
, 由服务器B和TGS共享的秘密密钥
, 由KAS创建,在A和TGS之间使用的会话密钥
, 由TGS创建,在A和B之间使用的会话密钥
, 使用密钥加密后的数据包
,, nounces(随机难题),用于阻止重放攻击的序列号
,, 通行票的截止日期(使用期限)
,,,: 通行票或者认证者的创建时间
: A对TGS使用的通行票,由KAS创建
: A对B使用的通行票,由TGS创建
图10.1 Kerberos 认证协议
图10.1表明了当客户(client)A要访问服务器B,在A和B之间建立相互认证时必须发生的步骤:
消息(1)A → KAS ,,,
消息(2)KAS → A 
消息(3)A → TGS ,,,,,
消息(4)TGS → A 
消息(5)A → B ,
消息(6)B → A 
为了开始一次会话,用户A在本地主机上登录,他输入用户名和口令,然后向通行票授予服务器请求服务。包含A的标识、TGS的名字、请求的通行票的截止日期和序列号(nonce)的消息(1),然后以明文的形式发送到KAS。KAS生成会话密钥Ka,tgs和通行票
。
使用用户A的秘密密钥对会话密钥、通行票、和序列号进行加密,而且在消息(2)中返回给A。在A的主机端,可以从口令重建,并得到会话密钥。客户A然后创建一个认证符(authenticator,鉴别码),而且在消息(3)中把这个认证符、通行票、要求的截止日期、下一步的序列号和服务器的名字都发送到TGS。TGS用密钥来解密通行票,并且与本地时钟比较验证通行票的有效性。然后,他用从通行票中得到的密钥检查认证符。如果所有的验证都成功了,TGS生成会话密钥和通行票
。
在消息(4)中,会话密钥和通行票被送到A,使用A和TGS共享的会话密钥加密。客户A存储该加密的通行票,解密新的会话密钥。在消息(5)中,A要求B有一个认证会话。这个消息包含和一个由会话密钥构造的认证符。B解密通行票,检查它的有效性,提取出会话密钥。下一步,B用密钥解密出认证符。在成功的解密和验证时间有效的情况下,B在消息(6)中用接收到的最后时间标记给出应答,采用会话密钥进行加密。A解密时间标记,将它同自己保存的备份进行比较。如果相等,则B就被认证了。
撤销如何撤销主体的访问权限呢?KAS和TGS的系统管理员必须更新他们的数据库,这样,访问权限对主体来说不再有效。这个访问权限对下一次的会话无效,即这个主体再次登录系统,或者从TGS请求一个通行票时。而这个主体已经拥有的通行票在超时以前都有效。例如,KAS通行票通常有大约一天的生存期。这是另外一个TOCTTOU问题的例子。
现在你不得不面临一个在方便和安全两个方面平衡的问题。如果TGS给出一个失效期太迟的通行票,主体则不需要频繁访问TGS,同时TGS可以偶尔离线,对用户方面也没有什么影响。然而,访问权限的撤销将有一个较长的时延影响。如果TGS提供的通行票具有一个较短的生命期,主体必须更有规律地更新他们的通行票,安全服务器的可用性对于系统性能来说变得越来越重要了。
邻域
Kerberos认证服务器是Kerberos领域的核心。一个Kerberos领域(realm),就是一个单一的管理范围,控制着对一个服务器集合的访问。为了准备和运行Kerberos,主体必须向KAS注册,TGS必须接收访问控制信息,所有需要的密钥必须由安全管理员存放在适当的位置。Kerberos具有集中式安全系统所有的优点。单个的安全策略通过有限数量的安全服务器来实施。因此,检查系统安装时是否遵守了安全策略,以及在需要的时候作某些变更还是相当容易的。
为了在Kerberos领域之间允许相互访问,你可以建立一个领域的层次。这导致在认证处理过程中增加了工作强度,因为不同的会话密钥要沿着认证服务器的连接链成对的交换。
小结为了对Kerberos有一个全面的评估,你就必须超出分析认证协议和理解密码算法强度。你也必须考察它的非密码的(non-cryptographic)安全特征。下列观点是一些这样调查研究部分。
·消息的及时(timeliness)由时间标记(time stamp)来检查。因此,在整个系统中要求合理的时钟同步,而且时钟自身必须被保护,以便防止攻击。安全时钟同步在本质上也要求认证。
·时间标记检查允许一些时钟有偏差。典型的采用五分钟的窗口是相当大的,且可能比较容易遭受重放攻击。
·服务器必须在线,在登录时KAS需要在线;请求通行票时也需要TGS。如在上面所说明的,TGS这种可使用性的要求可能被缓和。
·会话密钥(用于对称密码(cipher))由Kerberos服务器(认证服务器和通行票授予服务器)生成。当这个会话密钥在主体之间的后继通信中使用时,对服务器的信任必须包含信任:服务器将不会滥用他们的能力去窃听。
·Kerberos没有解决特权(通行票)的授予。
·口令猜测和口令欺骗攻击是可能的。
·密钥和通行票保存在客户的机器上。因此,你依赖于这个结点上的保护机制去维护Kerberos的安全性。只要Kerberos用户工作在简单终端上,这不是什么大不了的问题。一旦用户在PC机或者在多用户工作站上运行Kerberos,那么情况就发生了改变。
·区别Kerberos协议自身的安全性和Kerberos实现的安全性是非常重要的。例如,Kerberos版本4的一个实现据说使用了一个弱随机数产生器作为密钥生成器。因此,采用穷举法可以很容易地找到密钥。
10.2.2 DSSA/SPX
SPX是数字设备公司(Digital Equipment Corporation)开发的分布式系统安全体系结构(DSSA)的一个部分。DSSA是一个工作站网络的安全体系结构,由认证和其他的安全设施组成[116,151,160]。每一个结点都执行它自己的安全策略,用户必须信任他们登录的每个结点的操作系统。这样,用户授予特权给正在使用的结点的断言证明是正确的。DSSA/SPX使得“分布式认证安全服务”已经被采纳为RFC 1507。
在SPX的认证中包括证书(credential),证书包含主体的名字和长期使用的私有密钥。证书把主体的名字同他的公开密钥和认证标记(authentication token)绑定在一起。在SPX中证书代表一个用户。证书可以被存储在一个服务器上,初始化时要求用户的口令。作为选择,证书也可以存储在用户携带的智能卡(smart cards)上。在一个会话期间,最初的用户注册和认证是通过不同的服务器来执行的。
·证书管理机构(CA):提供公开密钥证书(certificate),可以脱机处理。仅在发布有效证书时,CA必须是可信任的。
·证书分发中心(CDC):存储由CA发行的证书。CDC的功能可以由命名服务提供。CDC在认证期间必须是联机的。
CDC不能损害认证协议的安全。如果它分发了无效的证书,协议运行将报错后终止。在这种考虑上,CDC不一定是可信任的,但是对于认证服务的可用性来说,它却是至关重要的。在实际实现时,CDC可以是分布式的。
证书的撤销可以通过维护一张证书撤销表实现,或者直接从CDC数据库中删除证书。在这种情况下,必须相信CDC正确地删除了证书。如果没有要求CDC进行在线认证,证书在截止日期前都是有效的。访问权限可以在单个结点上取消。
关于SPX的描述,我们将采用下面的约定:
·: 主体P的私有签名密钥;
·,: A的长期公开密钥和长期私有密钥;
·,: A的短期公开密钥和短期私有密钥,当A登录时生成;
·: 在对称加密算法中,用作A、B之间的会话密钥,由A生成;
·: 采用密钥对数据包进行加密;
·: 用密钥生成的数据包的数字签名;为了描述简单起见,我们假设,无论何时传送一个数字签名时,已经被签名的数据也包含在消息中;因此将表示数据包和对的签名两种数据。
·: 时间戳;
·,: 证书或者通行票的终止日期。
在该表示中,公开密钥被用于加密和对签名的验证,而私有密钥用于解密和签名。这只是为了简化描述,并不建议在实际中也这样实现。使用短期的公开密钥/私有密钥对可以避免长期密钥对的过分暴露。授权可以采用生成新的证书来实现。证书将用户身份绑定在一个短期私有密钥上。这个密钥对用户调用的服务必须是有效的。
图10.2 DSSA/SPX认证协议
在主体A、B之间的相互认证处理如图10.2所示。主体B的证书,由A所信任的证书管理机构CAa发布。证书采用这种形式:
。
交换的消息如下所示[151]:
消息(1)A → CDC: 
消息(2)CDC → A: 
消息(3)A →B: ,,,,
消息(4)B→CDC: 
消息(5)CDC→B: 
消息(6)B→A: 
在第一个消息中,申请者A向CDC请求验证者B的长期公开密钥。在消息(2)中,CDC用一个绑定了B的身份和它的公开密钥的证书来响应这个消息。这个密钥由A用CAa中的公开验证密钥来验证。现在A生成了一个会话密钥。这个密钥被用来生成一个认证符(authenticator)、一个A的短期公开密钥的签名通行票,即,和授权书(delegator)、。如果不想要授权,可用授权书作替代,于是密钥对于B来说是不可见的。这些数据域在步骤(3)的消息中被送到验证者。
在第4,5步中,验证者从CDC取回对于申请者长期公开密钥的证书。在有证书的情况下,B就可以认证申请者A的长期公开密钥,B用它自己的长期私有密钥解密数据,从授权书(delegator)中重新获得会话密钥。然后B使用会话密钥解密认证符,把它的时间标记同本地时钟相比较。下一步,B使用有书面证明的验证密钥,检查含有的通行票的签名。
最后的检查依赖于授权书(delegator)的格式。使用和,验证者(verifier)重新获得,且确认和是正确的密钥对。如果授权书已经被发送,验证者利用检查关于的签名。如果所有的检查都成功了,B完成在第6步中的相互认证,通过发送一个认证符作为响应。A使用会话密钥解密认证符,通过保存在本地的副本来验证。
10.2.3 个人加密设备在Kerberos系统中,用户仅仅必须记住他们自己的口令,应用服务器也只需要同通行票授予服务器共享一个密钥,其他所有与安全相关的信息都保存在几个中央服务器上。在DSSA系统中,用户(必须能够获得)保存一个私有密钥,几乎所有其他与安全相关的信息都由本地服务器管理。中央服务器仅仅是证书的储存库。
我们能够更进一步采用分散的方式,且在用户方存储更多的与安全相关的信息。用户可以携带个人加密设备(PCPs),即随身带的像智能卡或者PCMCIA卡那样的设备,使用这个设备从任何结点来访问分布式系统。PCP应该包含与用户关联的加密密钥、进一步的访问控制参数,和加密算法的实现等信息。
Fortezza卡,是为美国国防应用开发的PCMCIA卡,说明了这种方法。当颁发给用户一张卡时,在卡成为用户模式前,场地安全管理员装入用户的私有密钥。该卡将通过个人身份识别号码PIN机制被激活。通过用户在他们自己的PCMCIA卡上执行与安全相关的操作,Fortezza使得各个用户以安全的方式从任何一个结点访问分布式系统。
10.3 安全APIs
为了向更深一步提高分布式系统安全的综合体系结构,下面的三个问题必须被提出来。
1.分布式系统中的安全要求常常超过了纯粹的认证。
2.在分布式系统中不同的组件不必使用相同的安全机制(在本章中,你已经了解了作为用户认证的两种不同的体系结构)。因此,安全必须在各种各样的安全机制上实施。
3.用户和应用程序员不必是安全专家。你必须找到一个可行的方法给那些不知道安全的用户提供安全服务。
软件工程提出了能处理所有这些问题的一个非常确实的(well-established,)策略。系统被分解成多层。应用程序接口(APIs)允许应用程序在某一层调用底层的服务。通过隐藏实现的细节,API可以减轻应用程序员的与安全相关的任务,比如实现或者甚至选择加密算法。所需的安全专家的水平(安全意识,security awareness),是比较安全APIs的一个很好的尺度标准(yardstick)。
10.3.1 GSS-API
通用安全服务应用程序接口(GSS-API)最初被设计用来提高在基于Kerberos或基于分布式认证安全服务(DASS)的分布式安全体系结构之间的可移植性。GSS-API提供了面向连接应用的安全服务的简单接口。这些服务都可以在一定的底层机制和协议范围内实现,所以对不同的环境可以提高应用程序源级的可移植性。指导GSS-API设计的主要目标是:
·机制独立,GSS-API在通用级上定义了对强安全认证和其他安全服务的接口,它独立于特定的底层机制。安全服务可以通过对称密钥加密(例如,Kerberos)或者公开密钥加密(例如,X.509)实现。
·协议环境独立,GSS-API独立于使用的通信协议,允许在宽的协议范围内使用。
·对实现位置范围的适用性,在GSS-API实现的系统中,GSS-API客户不被限制驻留在系统定义的任何可信计算基(trusted computing base,TCB)的周边(perimeter)内。
对GSS-API来说有两个逻辑部分:与安全服务集合的通用接口,即完全的API,和提供安全服务机制的集合。
GSS-API的特征和概念一个典型的GSS-API调用者本身就是一个通信协议,调用GSS-API服务就是为了用认证、完整性和/或者机密性安全服务保护它的通信。接口驻留在本地系统中,通过一个库提供对GSS-API调用的入口。接口实现数据转换和对每一个已知的机制调用其接口的任务(roles),而对应用程序隐藏了机制的细节。GSS-API的基本安全元素是证书、标记(token)、安全上下文(context)和状态码。在对等层间初始化安全上下文的操作实现对等实体的认证,与提供每一个消息数据源的认证和数据完整性保护相分离。
过去习惯于提供安全服务的机制在每一次会话开始时选择,且在整个会话期间都保持不变。对GSS-API可利用的机制影响了这种机制的选择。在GSS-API那里多种机制是可利用的,调用者可以说明一个优先选择的列表。否则,系统选择一种缺省机制。
证书证书(credential)包括与安全相关的数据,这些数据都是在对等实体相互之间建立安全上下文要求的信息。没有标准的证书结构。由底层定义证书的内容,但是相同的结构可以由不同的机制使用。证书必须由底层系统正确操作,这样才能维护应用的安全。证书不作为GSS-API的调用参数传递,而是通过证书句柄的引用。
标记由调用者供给GSS-API接口调用的数据,转换成特定于机制格式的标记(Token)。GSS-API调用者接收这些由它的本地GSS-API实现程序提供给它的标记,再将这些标记传送给远程系统的一个同等层(peer)。这个同等层然后传送接收到的标记给它本地的GSS-API实现处理。这些标记对于调用者来说通常是没有含义的,它们的具体格式高度依赖于所使用的特殊机制。
安全上下文安全上下文(contexts)记录与安全服务管理有关的信息。使用证书在对等层(peer)之间建立安全上下文。在一对对等层之间多重上下文可能同时存在,使用相同的或者不同的证书集合。当证书过期的时候,使用不同证书的多种上下文共存允许适度的翻转。
状态码设置状态标志,以指出哪种特征是期望的,例如,指出相互认证是要求的状态标志MUTUAL_REQ_FLAG。状态码也支持安全上下文的设置,例如,指示一个安全上下文的初始化尚未完成的GSS_CONTINUE_NEEDED状态标志。大多数状态码是独立于机制的,而少数状态码可能特定于底层的安全机制。这些状态信息给GSS-API调用者一个机会,使得调用者根据与安全有关的调用执行有限制的因果关系检查。确信调用在正确的安全上下文中发出是调用者的责任。为了阐述调用者在管理任务中包含的范围,下面的表给出了在RFC 2078中规定的重要的状态返回值。
GSS_S_BAD_BINDINGS 信道绑定失配
GSS_S_BAD_MECH 不支持请求的机制
GSS_S_BAD_NAME 提供了无效的名字
GSS_S_BAD_NAMETYPE 提供了不支持类型的名字
GSS_S_BAD_STATUS 无效的输入状态选择符(selector)
GSS_S_BAD_SIG 标记完整性检查无效
GSS_S_CONTEXT_EXPIRED 规定的安全上下文过期
GSS_S_CREDENTIALS_EXPIRED 检测出过期的证书
GSS_S_DEFECTIVE_CREDENTIAL 检测到损坏的证书
GSS_S_DEFECTIVE_TOKEN 检查到损坏的标记
GSS_S_FAILURE 在GSS_API层失败,或是未指定的
GSS_S_NO_CONTEXT 规定了无效的安全上下文
GSS_S_NO_CRED 提供了无效的证书
GSS_S_BAD_QOP 不支持的QOP值
GSS_S_UNAUTHORIZED 未授权的操作
GSS_S_UNAVAILABLE 无效的操作
GSS_S_DUPLICATE_ELEMENT 复写了要求的证书元素
GSS_S_NAME_NOT_MN 名字包含了多种机制元素
GSS_S_COMPLETE 正常完成
GSS_S_CONTINUE_NEEDED 对请求的例程连续调用
GSS_S_DUPLICATE_TOKEN 检测出复写每个消息(per-message)标记
GSS_S_OLD_TOKEN 检测出每个消息标记超时
GSS_S_UNSEQ_TOKEN 检测出重新排序(早期)每个消息标记
GSS_S_GAP_TOKEN 跳过检测出的前任标记
接口描述存在四种类型的调用。
·证书管理调用,允许一个主体(principal)获取或者释放证书,以及查询各种证书的信息。
·上下文级的调用,例如,上下文的初始化、接受和删除等,也决定上下文的有效时间,和处理上下文的标记。
·每个消息(per-message)调用,提供加密(cryptographic,密码,加密)完整性和机密保护。
·支撑调用,处理一般的内务处理和支持例程,例如释放分配的内存和名字的比较。
下面的表列出了在RFC 2078中定义的所有的GSS_API调用。
证书管理调用:
GSS_Acquire_cred 获取使用的证书
GSS_Release_cred 在使用后释放证书
GSS_Inquire_cred 显示关于证书的信息
GSS_Add_cred 增量构造(construct)证书
GSS_Inquire_cred_by_mech 显示每个机制(per-mechanism)证书的信息
上下文级的调用:
GSS_Init_sec_context 初始化往外的(outbound)安全上下文
GSS_Accept_sec_context 接受往内的(inbound)安全上下文
GSS_Delete_sec_context 当不再需要时,清洗安全上下文
GSS_Process_context_token 处理接收到的在上下文中的控制标记
GSS_Context_time 表示关于上下文剩余的有效时间
GSS_Inquire_context 显示关于上下文的信息
GSS_Wrap_size_limit 决定GSS_Wrap标记容量限制
GSS_Export_sec_context 传送上下文到其他进程
GSS_Import_sec_context 输入传送的上下文
每个消息的调用:
GSS_GetMIC 接收从消息中分离出来的标记,应用完整性检查
GSS_VerifyMIC 验证与消息一起的标记的完整性检查
GSS_Wrap 签名,可自由选择的加密,封装
GSS_Unwrap 解封装,如果需要的话解密,验证完整性检查
支撑调用:
GSS_Display_status 转换状态码为可打印形式
GSS_Indicate_mechs 指示本地系统支持的机制类型(mech_types)
10.3.2 APIs和安全有效的提供安全服务,不仅仅依赖于有关的安全机制的正确实现,而且也依赖于正确的安全管理。当安全服务使用密码术(cryptography)时,密钥管理是安全管理的重要部分。然而,密钥管理常常是在服务请求执行之前已经完成的任务,不是在处理服务请求期间执行的任务。如图10.3所示,这个事实反映在像IBM安全层次结构这样的模型中,其中安全管理作为一个分离的问题出现,它同模型的其他层的关系是正交的。
图10.3 IBM安全体系结构
当然,安全管理与模型中的所有层发生关系,这是真的。当然,当设计者忽略了密钥管理的这个方面时,问题就出现了;而追求分层设计策略,就是为了使安全不感知的(security-unaware,不知道的,没觉察到的,未意识到的,没注意)应用程序编程员减轻与安全有关系的任务。为了达到这个目标,我们也必须分解密钥管理,且明确关于在应用责任范围内的安全管理的部分任务。密钥管理有很多方面,人们至少应该考虑下列的四个方面:
·密钥生成
·密钥存储
·密钥传输
·密钥使用最后一项谈到密钥,一个密钥仅仅用于一个目的,例如,或者用于生成数字签名,或者用于验证签名,但是从来不是同时用于这两项功能。这样的应用在金融部门是熟悉的,且被支持,例如,通过IBM的控制矢量,或者通过打过标签的密钥。但是,发自传统的操作系统安全的应用程序接口API,常常忽略了这个问题。
当然,存在两个安全接口的特定区域,这两个特定区域使得与密钥管理的关系变得特别简单。
1.密钥管理完全委托给在接口上面的层。较低的层假设它已授予了要求它执行任务的适当的密钥。
2.密钥管理完全委托给在接口下面的层。上层不执行任何密钥管理操作。
一个非常简单的密码模块(CM,cryptographic module),仅仅对给定的密钥和数据执行加密操作,可以通过第一类的接口使用它。密码模块必须依赖上层来阻止密钥的滥用和保证与安全相关的数据的真实性。
假设应用程序员不是安全专家,因此他们参加安全管理,应该尽可能少地受到信任,于是指望第二类接口。在这样的顶级接口下面的层提供比只实现密码算法多得多的功能。
GSS-API在哪方面适合这样的结构?关于每一个消息的调用,GSS-API是高级接口。关于安全管理方面,GSS-API是较低层的接口,即使如此,GSS-API仍然是在一个相当高的级。它依赖于较低的层来定义和保护大部分密钥管理数据。然而,有些安全管理任务必须由应用程序员来完成,它留给调用者很多机会来获得管理这些问题的权限。可能存在一个隐患,即在相当没有计划的方式下通过引入不断增加数量的安全管理特征,在GSS-API的管理方面的抽象层会被击垮。在成功发布的GSS-API之间的管理调用的数量一直在稳步增长。
10.4 CORBA安全
GSS-API是对于安全服务集合的接口。在分布式系统中,服务层确实是实施安全最适合的地方。
首先,分布式系统可能混合具有不同操作系统和不同硬件体系结构的计算机。使所有操作系统的设计者都一致同意对安全实施的公共标准,这也是不可能的情况,不能进一步考虑任何选择。因此,为了对用户提供统一的安全接口,必须把这些接口都保留在操作系统层的上面。
第二,考虑要求安全的应用软件。为了做安全工作,应用程序必须在某种方式下与底层的操作系统相互作用。如果应用程序编写者必须处理许多不同的操作系统,则成功的可能性再一次是不容乐观的。提供给应用程序编写者一个中间层,该层提供与底层操作系统的接口,这种方式明显是希望的。对象请求代理(object request broker,ORB)在用户和对象之间处理交互,在对象本身之间处理交互。
综合上述的要求,我们获得了图10.4中描述的解决方案。安全服务位于应用和操作系统的中间,而且提供了跨越在分布式系统中的所有组件上的公共层。
图10.4 在分布式系统中的保护
10.4.1 对象请求代理如果你有机会检查大公司的IT(信息技术)系统,你完全可能会发现,这个IT系统已经建立了好多年,它不断地增加新的应用,以满足用户要求的变化。并且,这些应用常常使用不同的语言编写,适用于不同的硬件和软件平台,且使用不同的数据格式。因此,在应用之间共享数据根本就不是一件容易的事情,会频繁地要求定制软件的解决方案。当数据必须在不同的组织之间进行共享的时候,同样的问题将在更大范围内重新出现。
分布式对象计算试图解决这种情况,改善应用的协同工作的能力。分布式对象计算建立在分布式计算的概念上,像客户服务器模型一样,也建立在面向对象的计算的概念上。应用也被认为一个对象。对象有它们自己的属性和方法,对象的属性仅仅可以通过对象的方法进行操作。对象请求代理是位于客户和服务器对象之间的“软件总线”,处理对象之间的所有通信。公共对象请求代理体系结构(CORBA),由对象管理组(OMG)开发,它是一个用于这种体系结构的工业标准[61]。
图10.5 CORBA方法调用
图10.5给出了分布式对象计算的特征。应用被分布跨越在客户和服务器上。在客户的存根程序(Stub)和在服务器的构架(skeleton)提供在应用和ORB库之间的接口。当客户的应用必须调用在服务器的一个方法时,会发生下述顺序的事件。
1.客户端的方法调用通过它的应用的存根程序(stub)来请求ORB功能。
2.在客户端的ORB库通过发送一个请求到活化(activation)组件来初始化对一个对象的绑定。
3.活化组件从存储仓库(repository)取回由方法调用寻址的对象的引用。
4.活化组件发动(launch)在服务器上的对象。
5.ORB库将对象的引用返回给客户。
6.执行方法调用。
ORB库包含了对象服务。已经规定的对象服务的完全列表在下面给出(在写这本书的时候,仅仅实现了其中的很少一部分),我们希望这些服务的名字是对它们的功能的充分表示。
·名字服务
·事件服务
·事务服务
·持久的对象服务
·发给许可证(licensing)服务
·生命周期服务
·并发控制服务
·时间服务
·具体化(externalization)服务
·查询服务
·关联(relationship)服务
·所有权(property)服务
·安全服务
·交易(trading)服务
·收集服务
10.4.2 CORBA安全模型为了理解CORBA安全体系结构设计者面对的任务,你必须知道他们的基本设计难题。灵活性和互操作性是在不同方向上施加的影响力。CORBA必须是灵活的,以便支持各式各样的应用和安全策略。CORBA也想提供一个框架结构,该结构允许在安全领域之间协同工作。协同操作要求具有一致性,一致性必须建立在某种标准的基础上。标准内在的特征又限制了可扩展性。CORBA提供了实现和管理安全服务的框架结构,它并没有规定任何安全机制。
CORBA安全必须在一个不断变化的环境中进行管理。分布式对象始终被创建、删除和修改。对象之间的交互可能是复杂的。有些应用是有安全意识的,明确地要求它们需要的保护。另一方面,对于安全不感知的应用来说,安全应该在任何方面都不涉及到应用的情况下实施。在请求服务时,必须授予对象以它们的权限,策略可以限制授权的范围。例如,一个策略可以规定目标对象可能被授予的特权,特权终止的时间,或者特权可以被调用的次数等。
具有相似保护要求的对象分组在一个域中。域安全策略由ORB强制实施。CORBA包含管理策略对象的接口,以及对这些接口的访问控制。CORBA并没有规定特定的策略。
ORBs之间的互操作性在技术级上由网桥、网关、ORB间的协议如通用ORBs间协议(GIOP),以及Internet ORB间协议(IIOP)支持。SECIOP是安全的ORB间(inter-ORB)协议。互操作性是一个难应付的问题,而且在编写本书时还没有ORB网桥实际上实现了。互操作性也要求在域之间的策略协议(agreement)。为了方便关于访问权限的统一解释,存在一组标准的访问权限:
·get得到
·set设置
·manage管理为了增加灵活性,还有一些定义了附加权限的选择项。CORBA安全服务包括:
·认证;
·安全上下文的建立;
·授权和访问控制:关于ACL、能力、或者基于角色的访问控制;
·消息保护:主要是通过加密,但是不排除其他的方式;
·审计
·不可否认(non-repudiation)
我们简要地讨论前面两个服务。
10.4.3 认证图10.6 描绘了在CORBA中认证的示意图。首先,用户签约雇用到一个ORB。用户发起人(sponsor),例如登录程序,传送用户身份和口令给主体认证者(Principal Authenticator)对象(步骤1)。主体认证者然后创建一个证书(Credentials)对象(步骤2)。这些证书包含用户的安全属性,比如认证身份、角色、特权。然后用户发起人传送一个对证书对象的引用到现行(Current)对象,现行对象代表了当前执行的上下文环境(步骤3)。
现在,用户想要调用一个服务(步骤4)。安全服务(Security services)协调在客户对象和服务器对象之间的访问。首先,在客户和服务器之间必须建立一个安全关联(绑定)。对于每一个安全关联来说,在客户端和服务器端都有一个安全上下文(Security Context)对象。代表性地,安全上下文包括加密算法的属性和一个对象有权使用的加密密钥。安全调用服务将检查这个联合是否已经存在。如果必须建立一个新的安全关联,则将调用一个拱顶(vault)服务。来自于现行对象的安全信息将用在获得相关属性的过程中(步骤5)。在安全不感知的应用中安全服务和操作都是隐藏执行的。建立起来的安全关联可用于其他的安全服务,例如,访问控制。
10.4.4 保证的安全或者保证的安全服务?
CORBA许诺了保证的安全。这个许诺能够成立吗?让我们考察实际情况。在CORBA内部,安全没有留给应用程序,所有的请求必须通过ORB,且ORB应用了安全控制。如果所有的安全服务都正确地安装了,而且如果用户没有办法旁路ORB,例如,通过对操作系统的直接调用,那么CORBA确实保证了安全。
图10.6 在CORBA中的认证
然而,CORBA不保证ORB不能被旁路,也不保证由CORBA安全服务使用的数据受到了正确的保护。TCB(可信计算基)包含了操作系统和所有曾保持了与安全有关的信息的机器硬件,比如加密密钥或者证书。安全进一步依赖于由CORBA服务使用的底层安全机制的强度。这些系统中的任何弱点允许对在ORB下面层的访问,会损害CORBA的安全。从这种意义上来说,CORBA根本不提供任何保证。为了公平,你不能且也不应该指望从一个安全框架结构得到更多。
CORBA是一个分布对象系统的规范。很多组织刚刚开始窥视实现CORBA和CORBA安全。在我们的分层模型中,向上走得越远,无懈可击的安全机制的实现就越困难。因此,实现者面对一个非常复杂的任务,他们仍然在努力奋斗以获得CORBA安全运行。所以,对于CORBA安全实际上可以提供多少保证,还没有经验。为了达到这些目标,在我们前面还有一个很长的曲折的学习过程。
进一步的阅读文献[83]和[159]详细阐述了分布式系统的认证原理和实践。Internet RFC1510[80]包含了Kerberos规范的详细说明。文献[15]给出了在开发Kerberos环境的上下文方面的Kerberos安全分析。Kerberos的扩充细化了它的访问控制特征,例如,在SESAME或者OSF DCE中通过特权属性证书(PACs),见[123]。
由IBM开发的KryptoKnight是Kerberos的一个替换方案。像Kerberos一样,KryptoKnight是一个集中式系统,其中安全服务器提供认证和密钥分发。在KryptoKnight中的密码协议使用完整性检查功能而不是加密,以避免出口问题[20]。
如果一个安全协议依赖于一个中央安全服务器,当服务器不能使用的时候,则系统做出访问控制的决策是困难的。因此,Horus安全体系结构在分布式系统中引入了故障容错。为了避免对单个的证书分发中心的苛刻的联机请求,秘密共享方案用来在很多服务器之间分发证书[126]。
GSS-API作为Internet RFC 1508在1993年9月发布。修订版本2在1997年1月的RFC 2078中公布[88]。
这里只是简单地介绍了CORBA,详细的规范说明和更多的论文可以去下面网址查找:
http://www.omg.org
http://www.acl.lanl.gov/CORBA
如果你更喜欢书籍,在书籍[106]和[121]对CORBA做了比较好的综述。
练习题练习10.1基于用户身份的访问控制策略在分布式系统时代以前就出现了。在分布式安全系统中的访问控制策略将仍然是基于用户身份的吗?探索对这样策略的替换方案。在分布式系统中,你何时想认证各别用户?
练习10.2 定义转换函数和,传送Lattice_1中的标签到Lattice_2中,则传送Lattice_2中的标签到Lattice_1中(图10.7)。这两个函数用来实现:如果来自使用Lattice_1的系统的主体或客体传送到使用Lattice_2的系统中,那么向下的信息流将被禁止。对于你的传送函数的选择,构造表格,说明他们在表中怎样被标签,如果他们从Lattice_1传送到Lattice_2,然后再回到Lattice_1(在数学术语上,这叫级联。)。对于原在Lattice_2中标签的项目做同样的传送。
图10.7
练习10.3 给出KryptoKnight协议的一个简短描述;与Kerberos比较,讨论它的优点和缺点。
练习10.4 设计一个Kerberos的扩展,它允许在域之间的访问。哪种管理配置必须安排在适当的位置,以使这种方案成为可实行的?在这个协议中,你将引入哪些附加的步骤?
练习10.5 证书可以通过证书撤销列表或者通过联机的撤销服务器被废除。在一个分布式系统中,用户都配备了持有他们的证书的个人加密设备,你更喜欢哪种解决方案?
练习10.6 当你在自己的系统中想要运行使用了GSS-API的应用程序时,你可能需要哪种附加的软件组件?
练习10.7 在分布式系统中,什么原因反对安全的局部实施?