Kerberos权威指南
第3章. 协议
(译注:本章译文中删除了原书中所有涉及Kerberos4的部分,包括Kerberos4的详细协议分析部分,以及Kerberos5到Kerberos4票据的转换部分。仅保留了原书Kerberos4章节中关于密钥版本号的部分,并将这部分插入了Kerberos5的协议描述中,因为这部分特性在Kerberos5中同样存在,并且没有变化。因此本章译文和原书的小节顺序存在一定差异,请注意。)
前两章中介绍了Kerberos身份验证系统的主要概念,并简要的在高层次上讨论了Kerberos的神奇之处。在本章中将继续深入讨论,并在基础层次上介绍Kerberos协议的本质。
创建一个协议来验证一个给定的网络,并且是不提供安全性的底层网络上的两个端点的身份,是一项艰巨的任务。Kerberos是在假设攻击者可以随意读取、复制和创建网络流量的场景下设计的。
Kerberos的基本操作基于Needham和Schroeder在1978年发表的一篇论文。由于Needham-Schroeder协议是构建Kerberos的基础,我们将从这里开始讨论。
Needham-Schroeder协议
施乐帕洛阿尔托研究中心(Xerox Palo Alto Research Center)的Roger Needham和Michael Schroeder在1978年12月发表了一篇论文,描述了他们设计的安全网络身份验证系统的框架。在这篇题为“在大型计算机网络中使用加密进行身份验证(Using Encryption for Authentication in Large Networks of Computers)”的论文中描述了两种不同的协议,可以为分布式计算机网络提供可靠、安全的身份验证服务。论文中描述的第一个协议使用私钥加密,正是这个协议构成了Kerberos网络身份验证协议的基础。
Needham和Schroeder概述了他们设计协议时的几个假设。其中一个假设是,恶意攻击者能够捕获网络上传输的数据包,并修改它们,然后发送自己伪造的数据包,这被作者描述为“极端观点”,但现在被认为是任何安全网络协议的常规需求。设计一个能够抵抗这类攻击的协议是很困难的,在讨论协议时,我将指出为了阻止这类攻击而做出的具体设计决策。
然而,作者们提出的其他假设,在实践中并不像在论文中那样站得住脚。在恶劣环境进行Kerberos操作时,用户的密钥很难通过穷举搜索来获得的假设是不成立的。不管你怎么去教育用户,用户还是会继续选择糟糕的密码。Needham-Schroeder协议,以及基本的Kerberos协议,都没有对用户的密钥提供针对离线暴力攻击或字典攻击的保护,我们将在第6章看到这一点。
Needham-Schroeder协议定义了协议交换中的三个参与者:客户端机器、客户端希望访问的服务器和身份验证服务器。客户端是任何请求身份验证的机器;通常是用户的个人桌面。服务器是任何应用程序服务器,例如邮件服务器,它提供客户端希望联系的服务。最后,身份验证服务器是一个专用服务器,它保存了网络上所有用户和服务器(“受信任的第三方”)的加密密钥的副本。这听起来应该很熟悉;这三个参与者都参与了Kerberos协议。
Needham-Schroeder协议背后的概念不是通过向身份验证服务器发送一个密码或密码等效项(例如密码的散列)来直接对用户进行身份验证。相反,Needham-Schroeder协议提供了一种机制,可以将短生命周期的加密密钥安全地分发给双方(客户端和服务器),这样就可以用加密密钥保护双方的通信。验证每个端点的标识碰巧是这个密钥交换过程的一个副作用。在讨论协议如何工作时,我们将看到这意味着什么。
协议从客户端联系身份验证服务器开始。客户端向身份验证服务器发送一条消息,其中包含它自己的标识和它希望联系的应用程序服务器的标识。此外,客户端在其请求中包含了一个临时生成值(nonce)或一个随机值(random value)。我们马上就会看到为什么这个随机值很重要。图3-1展示了客户端发送到身份验证服务器的信息。
身份验证服务器接收此信息,并定位它为客户端和应用程序服务器而存储的秘密加密密钥。它还创建了第三个密钥,即会话密钥,可用于支持客户端和应用程序服务器之间的安全通信。这个新密钥是由身份验证服务器生成的一个随机密钥,与客户端和服务器的长期密钥完全无关,并且永远不会被重复使用。
接下来是棘手的部分。在Needham-Schroeder协议中,身份验证服务器从来不直接与应用程序服务器通信,只会与客户端通信。因此,身份验证服务器向客户端发送一个回复,其中包括了会话密钥和双方的已验证标识。但是,如何才能保证这些消息不被正在监视网络通信的观察者发现,从而在会话密钥通过网络时拦截它们呢?而且,当客户端将会话密钥及其标识传输给应用程序服务器时,应用程序服务器如何知道客户端没有说谎,并且消息是真实的呢?
问题的答案涉及到多层的加密。首先,构造一条仅供应用程序服务器查看的消息。这个消息包括请求客户端的名称和会话密钥。为了确保这个消息的安全性,以防止恶意客户端对其进行窃听和篡改,需要使用应用程序服务器的长期密钥对其进行加密。由于只有应用程序服务器和身份验证服务器知道这个密钥,攻击者就无法解密此消息来更改内容或窃取会话密钥。在Kerberos术语中,这个加密消息也称为票据。
该消息被包装在另一条消息中,这条消息是为客户端准备的。这个客户端消息还包括应用程序服务器的名称、会话密钥的副本和第一个消息中最初发送的临时生成值的副本。然后,使用客户端的长期密钥对整个消息进行加密。所有信息组装和加密完成之后,身份验证服务器将其发送到客户端(图3-2)。
在Needham-Schroeder协议(以及Kerberos协议)中发生的所有加密很容易把人弄糊涂。因为通常有多个加密层在起作用,所以在讨论这些协议交换时,做一个现实世界中的类比是很有用的。
在本例中,一个很好的类比是一组嵌套的上锁的盒子。加密密钥可以看作是打开这些盒子的现实中的钥匙。因此,在这个类比中,用户的密码可以看成是物理的钥匙。该钥匙存在两个拷贝:用户持有一个拷贝,身份验证服务器持有另一个拷贝。服务密钥也是相同的情况:每个应用程序服务器都存在相同的两个钥匙,一个由应用程序服务器本身持有,另一个由身份验证服务器持有。使用用户的钥匙上锁的盒子,可以使用用户的钥匙的副本来开锁,对于服务的钥匙来说也是如此。
图3-3显示了身份验证服务器对客户端身份验证请求的响应。第一个盒子(票据的盒子)包含会话密钥的副本和一张包含客户端名称的纸;它被服务的钥匙锁上了。第二个盒子(回复的盒子)包含会话密钥的另一个副本,并使用用户的钥匙上锁了。并且,用服务的钥匙上锁的第一个盒子,被放入了第二个盒子中。通过将票据的盒子放入回复的盒子中,身份验证服务器确保了只有合法用户才能通过解锁回复的盒子来获取票据的盒子,因为只有用户拥有可以打开回复的盒子的钥匙。
注意,身份验证服务器并不知道发出请求的客户端是否就是他所声称的那个人。身份验证服务器将把这条加密消息返回给任何请求它的人,当然,前提是客户端的名称存在于身份验证服务器的加密密钥数据库中。看起来似乎在向任意服务请求身份验证时,任何用户都可以伪装成其他任意用户。但是,由于消息是用客户端密钥加密的,因此除了合法客户端以外,任何人都无法解密它。
因此,当客户端从身份验证服务器收到回复时,它首先使用其密钥(客户端的密码)来解密“外部”层。这会提示用户输入密码。如果密码无法解密消息,则身份验证请求失败。
接下来,是客户端把会话密钥发送回应用程序服务器(图3-4)。这是最后一条消息的内部内容发挥作用的地方。现在客户端已经删除了第一个加密“层”,客户端可以向应用程序服务器发送消息的内部部分(票据),其中包含了会话密钥的副本和客户端名称。由于此消息同样使用了应用程序服务器的密钥进行加密,因此只有应用程序服务器可以读取它,而攻击者无法修改它。
似乎我们已经做到了这一点:此后发生的任何使用会话密钥加密的通信,都应该只有客户端和应用程序服务器才能理解。客户端知道应用程序服务器是合法的,因为只有合法的应用程序服务器才能解密包含会话密钥的消息(因为它是使用应用程序服务器的长期密钥加密的)。应用程序服务器也知道客户端是合法的,因为只有合法的客户端才能解密包含转发到应用程序服务器的会话密钥和客户端标识的消息。
然而,对这个方案还可以进行另一种攻击,这时就是我们前面提到的临时生成值(nonce)发挥作用的地方了。
让我们看看攻击者想要冒充客户端的这种情况,攻击者可以伪装成受害者的身份与应用程序服务器通信。我们假设攻击者有能力读取所有网络消息,并发送他自己伪造的消息,但是他并不知道客户端或服务的长期密钥(显然,如果他知道的话,他冒充受害者就根本无需使用任何欺骗手法了)。
由于上述所有的协议交换的消息,都是通过不安全的网络发送的,因此,攻击者成功地获取了受害者向应用程序服务器发送的身份验证信息(消息包含会话密钥和客户端标识,都使用了应用程序服务器的密钥加密)。攻击者可以在稍后的某个时间,将该消息重新发送到应用程序服务器。由于消息可以被应用程序服务器解密,并生成有效的会话密钥和(受害者的)标识,因此它被当作合法消息接受,并完成会话验证。虽然攻击者不知道会话密钥,但是如果应用程序服务器只使用协议来确保身份验证,而不使用会话密钥来加密其与客户端的通信,那么攻击者就可以完全冒充受害者。
这类攻击被称为重播攻击,Needham-Schroeder协议提供了一种非常明显的解决方案来阻止这类攻击:强制客户端向应用程序服务器证明它确实知道会话密钥。为了做到这一点,应用程序服务器生成另一个随机数,再用会话密钥加密它,并将它发送给客户端。然后客户端解密数字,对其执行操作(例如,向其中添加一个数字),再用会话密钥加密新数字,并将消息发送回应用程序服务器。通过这个过程,只有知道会话密钥的可信客户端才能发回正确的数字,而重播以前的消息的观察者则不能(图3-5)。
在这里,我们看到了许多实际问题中的一个,即假定攻击者具有读取所有网络流量以及在网络上发送任意消息的能力的情况。Needham-Schroeder协议使用了一个交互式质询-响应系统,要求客户端证明它知道会话密钥。我们将在下一节中看到,Kerberos协议使用了一种稍微不同的,基于同步时钟的方法,来阻止重播攻击。我们还将在第6章中继续讨论重播攻击,以及一些Kerberos软件中出现的更多重播攻击场景。
Kerberos 5
如果您仔细地观察功能集,就会发现Kerberos 5是Kerberos 4的进化。Kerberos 5协议包含Kerberos 4协议中提供的所有功能,但带有更多扩展。不过从实现的角度来看,Kerberos 5是一种全新的协议,其内部与Kerberos 4完全不同。在本节中,我们将研究Kerberos 5中出现的新功能,以及协议提供的使这些新功能工作的新基础设施。
Kerberos 4 协议的缺点:它有一个相当笨拙的结构(例如,不使用标准字节顺序,而是有一个标记指定字节顺序来发送特定消息),它不具有可扩展性,因为它的许多字段是固定大小的。这些限制导致了许多其它问题,最明显的是对单DES加密密钥的依赖。在开发Kerberos 4时,针对DES的暴力攻击,在资源和时间上的花费仍然是非常昂贵的。但随着计算机速度继续呈指数级增长,现在已经到了资金充足的对手可以对DES发起暴力攻击的时候了。因此,需要一种更安全的加密算法和更长的加密密钥。不幸的是,由于Kerberos 4中的所有字段都是固定大小的,因此无法用另一种加密算法来更新Kerberos 4。
用户和管理员对新版Kerberos的另一个要求是支持凭证转发和委托。凭证转发允许用户在对远程服务器进行身份验证后,将票据转发到远程服务器。例如,假设一个用户刚刚通过Kerberos化的Telnet远程登录到应用程序服务器。使用Kerberos 4的情况下,如果用户希望从应用程序服务器向某个文件服务器进行身份验证,那么实际上会遇到问题。她必须通过kinit从远程服务器重新登录到Kerberos,以在远程服务器上获得新的票据授予票据。这就会导致安全问题,因为要重新对Kerberos进行身份验证,用户就必须重新输入密码,在telnet中,密码可能是通过网络明文发送的。另外,这意味着系统无法再提供单点登录。
Kerberos 5引入了对凭证转发的支持,这样,在前面的例子中,当用户登录到远程应用程序服务器时,她的票据授予票据能安全地传输到远程服务器上,并被远程服务器上的应用程序用于透明身份验证,以进一步使用Kerberos服务。
然而,这些增强和扩展引入了更多复杂性。为了创建可在多个平台上、可由多个供应商实现的、可扩展的协议,并确保所有这些实现都可以互操作,Kerberos开发团队选择了一种名为ASN.1的技术来描述他们的新Kerberos 5协议。ASN.1允许协议设计者使用抽象语言创建协议,自动化实现细节并允许未来进行扩展。我们将详细讨论ASN.1以及如何使用ASN.1定义Kerberos 5协议消息。
Kerberos 5协议正在不断地修订和开发。http://www.kerberos.isi.edu 的Kerberos主页,是Kerberos澄清的官方主页,Kerberos澄清是一组新起草的文档,用于取代当前的RFC 1510。Kerberos澄清文档被认为是Kerberos协议信息的权威来源。
(译注:现在Kerberos澄清文档所在网址已经改为 http://www.kerberos.info/,该网址中描述了所有关于Kerberos的白皮书和文档。)
世界上最短的ASN.1教程
ASN.1是Abstract Syntax Notation One的缩写。它定义了一种以抽象符号描述协议定义的方法,然后提供了一些方法将这些抽象定义转换为在通信网络上传输的字节流。一些协议就是使用ASN.1进行定义的:除了Kerberos 5之外,SNMP和LDAP也是使用ASN.1的常用协议。
正如我们在前面的Kerberos 4协议定义中看到的,在设计协议时,可扩展性是一个重要的属性。没有任何协议是一成不变的;如果协议从一开始就具有向前和向后兼容性,那么对于实现者和用户都将更加高效。一个手工设计并编码的协议设计(如Kerberos 4中的协议设计),除非在设计初始协议时就非常小心,否则很难在以后进行扩展。此外,对网络编码和解码模块进行手工编码容易产生Bug,当新的实现必须绕过或遵循初始实现中的Bug时,这些错误会导致互操作性问题。ASN.1可以帮助解决这两个问题。
ASN.1提供了一种语法,协议设计者可以用它来描述应用程序的协议。ASN.1还提供了几种内置类型,例如表示任意整数的INTEGER,和表示字符串的OCTET STRING。通过将这些基本类型链接在一起来构建更复杂的类型,实现者可以设计他们的协议的抽象语法,也就是以易于解析的形式对协议进行文本描述。用来描述这种抽象语法的语法,类似于描述计算机语言常用的BNF(Backus-Naur Form)。这里是一个ASN.1定义的例子:
Realm ::= GeneralString
PrincipalName ::= SEQUENCE {
name-type[0] INTEGER,
name-string[1] SEQUENCE OF GeneralString
}
这是Kerberos 5中的两个ASN.1定义,它们定义了Kerberos 5主体的各个部分。Realm(领域)的定义相当简单:领域可以定义为一串字符。PrincipalName由一种类型(表示名称的风格 —— Kerberos 5定义的几种名称的风格,包括以user@REALM和X.500的形式出现的传统Internet风格的名称)和一个有序字符序列组成,表示Kerberos主体的组成部分。定义了Realm和PrincipalName 之后,将来进行ASN.1定义时,可以在更复杂的结构中使用这些类型,比如ticket结构或authenticator结构。
现在我们已经有了这个抽象语法,我们需要某种方式来传输和接收符合我们语法的数据。例如,如果我们希望通过网络发送和接收一组PrincipalName,我们需要某种规则,来指定如何对字符串、整数和字符序列进行编码(我们还希望确保以正确的顺序进行处理!)。事实上,是有几种不同的用于传输的标准与编码ASN.1数据有关,但是Kerberos使用的是专有编码规则(Distinguished encoding Rule,简称DER)。DER接受一个ASN.1数据结构 —— 比如说,一个由应用程序填写了字段的PrincipalName —— 然后将其转换为传输语法,或者发送字节序列到使用基于相同ASN.1的协议的另一个应用程序。
我不会用DER怎么做这些肮活累活的细节来烦你,但是它的工作基于一个简单的原理:即所谓的TLV规则。TLV是指类型(type)、长度(length)和值(value)——在ASN.1结构中,为每个数据字段发送三段信息。类型指的是数据所代表的ASN.1类型:一个字节常量用来表示GeneralStrings,另一个字节表示INTEGER数据,依此类推。此外,可以将标签(label)添加到每个字段的类型中,如上面例子中的方括号所示。标签确保了数据的顺序被保留,并且接收方可以识别任何可选的或丢失的数据。随后发送的是被编码数据的长度,最后发送数据本身。通过所有这些发送的信息,接收方主机可以根据传输语法重构出原始数据的结构。
有了ASN.1抽象语法,专门的ASN.1编译器就可以读取抽象语法并生成程序代码,并将匹配抽象语法的给定数据结构转换为传输语法,反之亦然。ASN.1编译器可以自动生成发送和接收编码协议消息的代码,使得协议实现者有更多时间来编写专用于其协议的程序逻辑。
对学习更多有关ASN.1的知识感兴趣的读者可以阅读有关ASN.1、BER和DER的非专业指南,从RSA实验室网站 http://www.rsasecurity.com/rsalabs/pkcs/index.html 可以获得多种格式的指南。
(译注:书中提到的网址已经失效,可以如下网址在线阅读 http://luca.ntop.org/Teaching/Appunti/asn1.html 。PDF版本可访问 https://homepages.dcc.ufmg.br/~coelho/nm/asn.1.intro.pdf)
此外,对于那些对更多技术细节感兴趣的人,可以从 http://www.oss.com/asn1/dubuisson.html 下载免费的ASN.1文档。
(译注:书中提到的网址已经失效,新网址为 http://www.oss.com/asn1/resources/books-whitepapers-pubs/asn1-books.html#dubuisson)
身份验证服务器(AS)和票据授予服务器(TGS)
在Kerberos 5中,AS和TGS交换背后的思想没有变化。由于Kerberos 5中主体的命名约定不同,票据授予服务器的名称稍有变化。例如,在Kerberos 5中,WEDGIE.ORG领域的票据授予服务器的主体名是krbtgt/WEDGIE.ORG@WEDGIE.ORG。
但是,Kerberos 5中更改了一些协议级别的细节。我们已经讨论了最重要的一个,即使用ASN.1来正式地描述和编码新协议。此外,在Kerberos 5的开发过程中进行的另一个协议级更改,是消除在身份验证服务器和票据授予服务器的KDC应答过程中发生的双重加密。回想一下上面关于Kerberos 4协议的讨论,在AS或TGS应答中本质上有两层加密;使用服务密钥加密的票据包含在使用用户密钥加密的回复消息中。
这种双重加密被证明是不必要的,因此Kerberos 5将两个加密的消息串联起来,而不是将票据嵌套在回复消息中。这一步提高了效率和性能,并且不会降低消息的安全性。因为两个消息仍然使用各自的密钥进行加密,所以没有相关加密密钥来解密消息的攻击者是无法读取的。
新的加密选项
Kerberos 5中新支持的多重加密类型,意味着在一个给定的Kerberos协议事务中可以使用多个加密类型。下面列出的每种消息均可使用不同的加密类型:
票据(Ticket)
与票据关联的加密类型,用于在TGS中或AS的回复中加密服务票据。因为票据是用服务的加密密钥加密的,也只能由服务解密,所以票据的加密类型,由发出票据的服务所支持的最高强度加密类型决定。
回复(Reply)
KDC给客户端的回复的加密类型,是指回复中使用用户的加密密钥进行加密的部分。因为客户端必须解密回复,所以回复的加密类型由客户端支持的最高强度加密类型决定。
会话密钥(Session key)
由于会话密钥在客户端和应用程序服务器之间共享,因此会话密钥的加密类型是服务和客户端都支持的最大强度加密算法。例如,如果客户端支持单DES和三重DES,而服务只支持单DES,那么KDC将为该服务发出单DES的会话密钥。
图3-10显示了在典型的TGS回复中每个加密密钥的作用位置。
为什么要分离加密类型?换句话说,这是为了支持不同的Kerberos 5实现之间的互操作、基于Kerberos 4的旧应用程序之间的互操作,以及不同加密类型的Kerberos 5实现之间的互操作。
这种细粒度的控制,使得任何支持的加密类型的组合,都能够在Kerberos网络上互操作,只要涉及的三方(应用程序服务器、客户端和KDC)都支持至少一种共同的加密类型。当在KDC上创建主体时,通常会使用其支持的所有加密类型来存储其加密密钥的副本。因此,KDC可以使用每个参与方都支持的加密类型中最安全的加密类型,来响应请求。
不幸的是,尽管这个方案相当灵活,但也会导致难以跟踪的问题。我们将在第5章中看到更多关于加密类型不匹配的问题。
票据选项
Kerberos 5包含一些高级特性,允许用户对Kerberos票据进行更多的控制。Kerberos 5中添加了以下标志:
可转发的票据(Forwardable tickets)
用户可以请求可转发的票据。可转发的票据可以转发到另一台主机 —— 因此得来了这个名称 —— 并且票据在新主机上使用是有效的。一个常见的特殊情况是可转发的票据授予票据。一个可转发的TGT可以转发到另一台主机,并且可以使用原来的TGT在目标主机上获得一个新的TGT,而不需要用户再次输入密码。例如,如果用户使用Kerberos身份验证登录到一台主机,现在用户在目标主机上使用Kerberos软件之前,必须先获取一个新的TGT。相反,如果用户有一个可转发的票据,并将他的TGT作为登录过程的一部分转发到目标主机,那么用户现在就有了一个TGT的副本,该副本对于来自新主机的任何进一步的Kerberos票据请求都是有效的。通过请求可转发的TGT,用户可以享受单点登录的好处,即使是任意嵌套的凭证委托,也是如此。
可代理的票据(Proxiable tickets)
你还可以在票据上设置可代理标志。可代理的票据类似于可转发的票据,因为它们都可以转移到另一台主机。然而,一个可代理的TGT只能用于获得更后面的服务票据;它不能用于在目标主机上获取新的TGT。从这个意义上讲,可代理的票据不如可转发的票据功能强大,并且在实践中并不常用。
可更新的票据(Renewable tickets)
在Kerberos 4中,为了减少用户凭证被盗时的漏洞窗口时间,票据的生命周期受到了限制。Kerberos 5引入了一个两层的生命周期方案,它结合了较长生命周期的优点和较短生命周期的安全性。当用户请求一个可更新的票据时,他将获得一个具有标准生命周期和可更新生命周期的票据。此票据仅在标准生命周期内有效,但可以在票据到期(标准生命周期结束)之前的任何时间提交回KDC进行更新。KDC可以拒绝验证票据,例如,如果同一时间报告了票据已被攻破的情况。否则,KDC将验证票据,并返回一个新票据。可以重复此过程,直到票据的可更新生命周期最终到期。
未来日期的票据(Postdated tickets)
未来日期的票据是指在未来某一特定日期之前无效的票据。如果在嵌入到票据中的开始日期之前,提交了未来日期的票据进行验证,则将拒绝该票据。对于计划在将来某个时候运行的需要Kerberos身份验证的作业,例如批处理或集群作业,未来日期的票据非常有用。这个选项在实践中并不常用,事实上,有些实现(如微软的实现)是不支持发行未来日期的票据的。
预身份验证(Pre-Authentication)
原始的Kerberos 4协议很容易受到离线字典和暴力攻击,我们将在第6章中看到这一点。此漏洞源于这样一个事实,即KDC会为请求任何主体(假定所请求的主体存在于Kerberos数据库中)的任何客户端都发出加密的TGT。由于KDC很乐意向任何请求者提供使用主体的密钥加密的票据,因此可以进行脱机攻击来确定主体密钥。用户通常选择糟糕的密码这一事实,更加剧了该漏洞。
为了使这种攻击更加困难,Kerberos 5引入了预身份验证(参见图3-11)。预身份验证在KDC为特定主体发出票据之前,要求请求者证明自己的身份。Kerberos澄清文档定义了几种类型的预身份验证。但是,通常的实现只有通过加密的时间戳(PA-ENC-TIMESTAMP)进行预身份验证的方法。
预身份验证由KDC策略控制。如果用户试图通过AS交换获取初始票据,但是KDC要求预身份验证时,KDC将发送KRB_ERROR消息,而不是AS_REP消息来回复客户机的AS请求。这个KRB_ERROR消息告诉客户端需要预身份验证。客户端生成所需的预身份验证数据,并重新发送附加了预身份验证数据的AS_REQ消息。如果预身份验证数据被KDC接受,它将响应一个包含了客户端的初始票据的AS回复。否则,KDC将返回另一个KRB_ERROR消息,该消息指示预身份验证失败,并且客户端将不会收到初始的票据授予票据。
我们将在第6章中更详细地探讨预身份验证的实际安全问题。
其他协议特性和扩展
还有一些用于增强Kerberos的有用的扩展,目前已经进入了标准化轨道。其中有两个这样的建议,即所谓的PKINIT和PKCROSS,分别引入了公钥加密(public-key encryption)来增强用户对KDC的初始身份验证和跨领域(cross-realm)身份验证。这些建议还没有标准化,但是已经有一些可用的早期实现。在第10章中,我们将看到PKINIT和PKCROSS,对比当前Kerberos标准中的标准初始身份验证和跨领域功能的方面,所带来的好处。
String-to-Key转换
与Kerberos 4一样,Kerberos 5也需要一个函数,用于将可读的字符串密码转换为供内部使用的加密密钥。但是,Kerberos 5对这个过程做了一些更改,其中最重要的更改是Kerberos 5支持任意数量的任意密钥大小的加密算法。此外,Kerberos 5会强制加盐(添加一段数据到用户密码中),以增强其抵抗暴力攻击的能力。通常,盐是完整的主体名称 —— 但也可以是KDC指定的其它盐。
密码修改
当前Kerberos 5中密码修改协议的状态类似于Kerberos 4;不幸的是,与Kerberos 4一样,密码修改被视为事后的想法。最初由RFC 1510定义的Kerberos 5规范,没有定义客户端可以修改自己的密码的方法。较早的MIT Kerberos 5实现使用管理协议来执行密码修改,但是由于每个实现使用了不同的管理协议,所以在实现之间是不可互操作的。一种用于Kerberos 5密码修改的标准协议是在1998年作为Internet草案提出的,名为Horowitz密码修改协议(Horowitz password-changing protocol)。较新的MIT版本(1.2及以上版本)和Heimdal Kerberos,以及基于Windows 2000和2003的Active Directory,都支持Horowitz密码修改协议。其它实现,如Solaris的SEAM,不支持这个协议,因此不能与任何其它密码修改实现进行互操作。
目前正在讨论一项新的建议草案,以取代Horowitz密码修改协议。Kerberos Set/Change Password Version 2是当前的Kerberos密码修改的Internet草案。与Horowitz密码修改协议相比,这个新建议有几个优点。首先,它为管理员提供了重置其他用户密码的功能,并允许用户更改自己的密码。此外,这个建议允许在密码被拒绝的情况下将更多细粒度的信息返回给客户端。由于这个建议还在开发过程中,对新的Kerberos Set/Change Password Version 2协议的细节感兴趣的读者,可以在http://www.kerberos.isi.edu找到更多信息。
(译注:关于Kerberos Set/Change Password Version 2建议草案的讨论,在2009年5月7日已经过期,详情可见 https://datatracker.ietf.org/doc/draft-ietf-krb-wg-kerberos-set-passwd/history/。目前MIT Kerberos使用的仍然是Horowitz密码修改协议。)
密钥版本号(The Key Version Number)
密钥版本号通常缩写为kvno,用于区分为给定主体存储的不同加密密钥。例如,如果用户更改了密码,那么他的主体就有一个与之关联的新加密密钥。当Kerberos KDC在Kerberos数据库中存储新的加密密钥时,它的密钥版本号会增长。类似地,如果服务的长期密钥被更改,其密钥版本号也会更改。
在处理用户主体时,密钥版本号并不重要。但是,当使用Kerberos化的服务时,它们就变得重要起来。为了使Kerberos化的服务能够读取由客户端进行身份验证时发送的票据内容,存储在服务的keytab中的加密密钥和密钥版本号必须与存储在Kerberos数据库的加密密钥和密钥版本号相匹配。加密密钥或密钥版本号不匹配将导致解密过程失败。
一些与Kerberos有关联的协议的简称
最后,在实现Kerberos身份验证系统时,会遇到一些严格说来与Kerberos没有直接关系的协议。
通用安全服务API(Generic Security Services API,简称GSSAPI)
通用安全服务API,顾名思义,它并不特定于任何身份验证技术。因此,在一本关于Kerberos的书中提到它似乎有点不合适。然而,协议实现者广泛使用了GSSAPI作为在其应用程序中实现Kerberos 5支持的手段。通过使用GSSAPI,协议获得了“免费”使用其它强身份验证方法的能力,而且GSSAPI层还使实现者避免了受到原始Kerberos 5 API复杂性的影响。
GSSAPI面向希望在其协议中添加强身份验证支持的客户端/服务器应用程序的开发人员。它提供了一个通用接口和消息格式,可以封装来自任何具有GSSAPI兼容库的身份验证方法的身份验证交换。GSSAPI将应用程序编程人员与特定的编程接口隔离开来,以实现特定的身份验证方法。GSSAPI还提供了一种标准的消息格式,因此协议可以支持许多不同的身份验证方法,而无需更改协议本身。GSSAPI本身不定义协议、身份验证或安全机制;相反,它通过为安全服务提供统一的、通用的API,使应用程序编程人员更容易支持多种身份验证机制。
大多数Kerberos 5实现还包括一个GSSAPI库。这意味着所有支持GSSAPI的应用程序也支持Kerberos 5。值得注意的例外是Windows的Kerberos实现,它不包含GSSAPI支持,而是包含一个微软特定的API,即安全支持提供器接口(Security Support Provider Interface,简称SSPI)。SSPI与GSSAPI不兼容;也就是说,为GSSAPI编写的程序不能使用SSPI进行编译。相反,为SSPI编写的应用程序可以与GSSAPI应用程序兼容。因此,SSPI客户端可以与GSSAPI服务器通信。微软提供了一些示例代码,演示了如何实现这种网络消息级的互操作性。
虽然GSSAPI基本上是标准化的,但是在可用实现的C语言绑定之间仍然存在一些差异,特别是在MIT和Heimdal实现的GSSAPI之间。在配置阶段,大多数开源软件将检测你拥有的GSSAPI实现,并编译出适当的代码来使用它,但仍然有些软件可能只能使用其中一个实现。统一这些API的工作正在进行中。
定义GSSAPI的相关标准文档包括RFC 2743,它记录了基本的GSSAPI消息类型;RFC 1509,它定义了C语言绑定和API;RFC 1964,它定义了Kerberos 5 的GSSAPI机制。
简单且受保护的GSSAPI协商机制(Simple and Protected GSSAPI Negotiation Mechanism,简称SPNEGO)
GSSAPI解决了向不同的身份验证机制提供单一API的问题。然而,它并没有解决协商中使用何种机制的问题。实际上,为了让GSSAPI发挥作用,彼此通信的两个应用程序必须提前知道并同意它们计划使用的身份验证机制。由于大多数GSSAPI实现只支持一种机制(即Kerberos 5),所以这通常不是问题。但是,如果有多种机制可供选择,则需要一种方法来安全地协商客户端和服务器之间相互支持的身份验证机制。这个功能由RFC 2478文档中记载的SPNEGO执行。
微软在Windows 2000及以上版本的Kerberos和SSPI实现中包含了一个SPNEGO的实现。目前还没有一个被广泛接受的Unix开源SPNEGO实现,但是现在正在开发一个这样的实现。此外,微软在其网站上有一些示例代码,作为其关于通过协商协议进行HTTP身份验证的三篇文章的一部分,提供了一个简单的方法来解析SPNEGO消息。许多基于微软的产品,包括Exchange SMTP、通过SMB提供的文件服务,以及IE和IIS的WEB身份验证,都使用SPNEGO协商身份验证机制。
《Kerberos权威指南》中文精读系列回顾:
《Kerberos权威指南》中文精读系列:第1章 - 概述
《Kerberos权威指南》中文精读系列:第2章 - 拼图碎片