谈谈基于Kerberos的验证.docx

上传人:b****6 文档编号:8910518 上传时间:2023-02-02 格式:DOCX 页数:13 大小:105.35KB
下载 相关 举报
谈谈基于Kerberos的验证.docx_第1页
第1页 / 共13页
谈谈基于Kerberos的验证.docx_第2页
第2页 / 共13页
谈谈基于Kerberos的验证.docx_第3页
第3页 / 共13页
谈谈基于Kerberos的验证.docx_第4页
第4页 / 共13页
谈谈基于Kerberos的验证.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

谈谈基于Kerberos的验证.docx

《谈谈基于Kerberos的验证.docx》由会员分享,可在线阅读,更多相关《谈谈基于Kerberos的验证.docx(13页珍藏版)》请在冰豆网上搜索。

谈谈基于Kerberos的验证.docx

谈谈基于Kerberos的验证

谈谈基于Kerberos的WindowsNetworkAuthentication-PartI

前几天在给人解释Windows是如何通过Kerberos进行Authentication的时候,讲了半天也别把那位老兄讲明白,还差点把自己给绕进去。

后来想想原因有以下两点:

对于一个没有完全不了解Kerberos的人来说,Kerberos的整个Authentication过程确实不好理解——一会儿以这个Key进行加密、一会儿又要以另一个Key进行加密,确实很容易把人给弄晕;另一方面是我讲解方式有问题,一开始就从Kerberos的3个Sub-protocol全面讲述整个Authentication过程,对于一个完全不了解Kerberos的人来说要求也忒高了点。

为此,我花了一些时间写了这篇文章,尽量以由浅入深、层层深入的方式讲述我所理解的基于Kerberos的WindowsNetworkAuthentication,希望这篇文章能帮助那些对Kerberos不明就里的人带来一丝帮助。

对于一些不对的地方,欢迎大家批评指正。

一、 基本原理

Authentication解决的是“如何证明某个人确确实实就是他或她所声称的那个人”的问题。

对于如何进行Authentication,我们采用这样的方法:

如果一个秘密(secret)仅仅存在于A和B,那么有个人对B声称自己就是A,B通过让A提供这个秘密来证明这个人就是他或她所声称的A。

这个过程实际上涉及到3个重要的关于Authentication的方面:

∙Secret如何表示。

∙A如何向B提供Secret。

∙B如何识别Secret。

基于这3个方面,我们把KerberosAuthentication进行最大限度的简化:

整个过程涉及到Client和Server,他们之间的这个Secret我们用一个Key(KServer-Client)来表示。

Client为了让Server对自己进行有效的认证,向对方提供如下两组信息:

∙代表Client自身Identity的信息,为了简便,它以明文的形式传递。

∙将Client的Identity使用KServer-Client作为PublicKey、并采用对称加密算法进行加密。

由于KServer-Client仅仅被Client和Server知晓,所以被Client使用KServer-Client加密过的ClientIdentity只能被Client和Server解密。

同理,Server接收到Client传送的这两组信息,先通过KServer-Client对后者进行解密,随后将机密的数据同前者进行比较,如果完全一样,则可以证明Client能过提供正确的KServer-Client,而这个世界上,仅仅只有真正的Client和自己知道KServer-Client,所以可以对方就是他所声称的那个人。

Keberos大体上就是按照这样的一个原理来进行Authentication的。

但是Kerberos远比这个复杂,我将在后续的章节中不断地扩充这个过程,知道Kerberos真实的认证过程。

为了使读者更加容易理解后续的部分,在这里我们先给出两个重要的概念:

∙Long-termKey/MasterKey:

在Security的领域中,有的Key可能长期内保持不变,比如你在密码,可能几年都不曾改变,这样的Key、以及由此派生的Key被称为Long-termKey。

对于Long-termKey的使用有这样的原则:

被Long-termKey加密的数据不应该在网络上传输。

原因很简单,一旦这些被Long-termKey加密的数据包被恶意的网络监听者截获,在原则上,只要有充足的时间,他是可以通过计算获得你用于加密的Long-termKey的——任何加密算法都不可能做到绝对保密。

在一般情况下,对于一个Account来说,密码往往仅仅限于该Account的所有者知晓,甚至对于任何Domain的Administrator,密码仍然应该是保密的。

但是密码却又是证明身份的凭据,所以必须通过基于你密码的派生的信息来证明用户的真实身份,在这种情况下,一般将你的密码进行Hash运算得到一个Hashcode,我们一般管这样的HashCode叫做MasterKey。

由于HashAlgorithm是不可逆的,同时保证密码和MasterKey是一一对应的,这样既保证了你密码的保密性,有同时保证你的MasterKey和密码本身在证明你身份的时候具有相同的效力。

∙Short-termKey/SessionKey:

由于被Long-termKey加密的数据包不能用于网络传送,所以我们使用另一种Short-termKey来加密需要进行网络传输的数据。

由于这种Key只在一段时间内有效,即使被加密的数据包被黑客截获,等他把Key计算出来的时候,这个Key早就已经过期了。

二、引入KeyDistribution:

KServer-Client从何而来

上面我们讨论了KerberosAuthentication的基本原理:

通过让被认证的一方提供一个仅限于他和认证方知晓的Key来鉴定对方的真实身份。

而被这个Key加密的数据包需要在Client和Server之间传送,所以这个Key不能是一个Long-termKey,而只可能是Short-termKey,这个可以仅仅在Client和Server的一个Session中有效,所以我们称这个Key为Client和Server之间的SessionKey(SServer-Client)。

现在我们来讨论Client和Server如何得到这个SServer-Client。

在这里我们要引入一个重要的角色:

KerberosDistributionCenter-KDC。

KDC在整个KerberosAuthentication中作为Client和Server共同信任的第三方起着重要的作用,而Kerberos的认证过程就是通过这3方协作完成。

顺便说一下,Kerberos起源于希腊神话,是一支守护着冥界长着3个头颅的神犬,在keberosAuthentication中,Kerberos的3个头颅代表中认证过程中涉及的3方:

Client、Server和KDC。

对于一个WindowsDomain来说,DomainController扮演着KDC的角色。

KDC维护着一个存储着该Domain中所有帐户的AccountDatabase(一般地,这个AccountDatabase由AD来维护),也就是说,他知道属于每个Account的名称和派生于该AccountPassword的MasterKey。

而用于Client和Server相互认证的SServer-Client就是有KDC分发。

下面我们来看看KDC分发SServer-Client的过程。

通过下图我们可以看到KDC分发SServer-Client的简单的过程:

首先Client向KDC发送一个对SServer-Client的申请。

这个申请的内容可以简单概括为“我是某个Client,我需要一个SessionKey用于访问某个Server”。

KDC在接收到这个请求的时候,生成一个SessionKey,为了保证这个SessionKey仅仅限于发送请求的Client和他希望访问的Server知晓,KDC会为这个SessionKey生成两个Copy,分别被Client和Server使用。

然后从Accountdatabase中提取Client和Server的MasterKey分别对这两个Copy进行对称加密。

对于后者,和SessionKey一起被加密的还包含关于Client的一些信息。

KDC现在有了两个分别被Client和Server的MasterKey加密过的SessionKey,这两个SessionKey如何分别被Client和Server获得呢?

也许你马上会说,KDC直接将这两个加密过的包发送给Client和Server不就可以了吗,但是如果这样做,对于Server来说会出现下面两个问题:

∙由于一个Server会面对若干不同的Client,而每个Client都具有一个不同的SessionKey。

那么Server就会为所有的Client维护这样一个SessionKey的列表,这样做对于Server来说是比较麻烦而低效的。

∙由于网络传输的不确定性,可能出现这样一种情况:

Client很快获得SessionKey,并将这个SessionKey作为Credential随同访问请求发送到Server,但是用于Server的SessionKey确还没有收到,并且很有可能承载这个SessionKey的永远也到不了Server端,Client将永远得不到认证。

为了解决这个问题,Kerberos的做法很简单,将这两个被加密的Copy一并发送给Client,属于Server的那份由Client发送给Server。

可能有人会问,KDC并没有真正去认证这个发送请求的Client是否真的就是那个他所声称的那个人,就把SessionKey发送给他,会不会有什么问题?

如果另一个人(比如ClientB)声称自己是ClientA,他同样会得到ClientA和Server的SessionKey,这会不会有什么问题?

实际上不存在问题,因为ClientB声称自己是ClientA,KDC就会使用ClientA的Password派生的MasterKey对SessionKey进行加密,所以真正知道ClientA的Password的一方才会通过解密获得SessionKey。

 

三、引入Authenticator-为有效的证明自己提供证据

通过上面的过程,Client实际上获得了两组信息:

一个通过自己MasterKey加密的SessionKey,另一个被Sever的MasterKey加密的数据包,包含SessionKey和关于自己的一些确认信息。

通过第一节,我们说只要通过一个双方知晓的Key就可以对对方进行有效的认证,但是在一个网络的环境中,这种简单的做法是具有安全漏洞,为此,Client需要提供更多的证明信息,我们把这种证明信息称为Authenticator,在Kerberos的Authenticator实际上就是关于Client的一些信息和当前时间的一个Timestamp(关于这个安全漏洞和Timestamp的作用,我将在后面解释)。

在这个基础上,我们再来看看Server如何对Client进行认证:

Client通过自己的MasterKey对KDC加密的SessionKey进行解密从而获得SessionKey,随后创建Authenticator(ClientInfo+Timestamp)并用SessionKey对其加密。

最后连同从KDC获得的、被Server的MasterKey加密过的数据包(ClientInfo+SessionKey)一并发送到Server端。

我们把通过Server的MasterKey加密过的数据包称为SessionTicket。

当Server接收到这两组数据后,先使用他自己的MasterKey对SessionTicket进行解密,从而获得SessionKey。

随后使用该SessionKey解密Authenticator,通过比较Authenticator中的ClientInfo和SessionTicket中的ClientInfo从而实现对Client的认证。

为什么要使用Timestamp?

到这里,很多人可能认为这样的认证过程天衣无缝:

只有当Client提供正确的SessionKey方能得到Server的认证。

但是在现实环境中,这存在很大的安全漏洞。

我们试想这样的现象:

Client向Server发送的数据包被某个恶意网络监听者截获,该监听者随后将数据包座位自己的Credential冒充该Client对Server进行访问,在这种情况下,依然可以很顺利地获得Server的成功认证。

为了解决这个问题,Client在Authenticator中会加入一个当前时间的Timestamp。

在Server对Authenticator中的ClientInfo和SessionTicket中的ClientInfo进行比较之前,会先提取Authenticator中的Timestamp,并同当前的时间进行比较,如果他们之间的偏差超出一个可以接受的时间范围(一般是5mins),Server会直接拒绝该Client的请求。

在这里需要知道的是,Server维护着一个列表,这个列表记录着在这个可接受的时间范围内所有进行认证的Client和认证的时间。

对于时间偏差在这个可接受的范围中的Client,Server会从这个这个列表中获得最近一个该Client的认证时间,只有当Authenticator中的Timestamp晚于通过一个Client的最近的认证时间的情况下,Server采用进行后续的认证流程。

TimeSynchronization的重要性

上述基于Timestamp的认证机制只有在Client和Server端的时间保持同步的情况才有意义。

所以保持TimeSynchronization在整个认证过程中显得尤为重要。

在一个Domain中,一般通过访问同一个TimeService获得当前时间的方式来实现时间的同步。

双向认证(MutualAuthentication)

Kerberos一个重要的优势在于它能够提供双向认证:

不但Server可以对Client进行认证,Client也能对Server进行认证。

具体过程是这样的,如果Client需要对他访问的Server进行认证,会在它向Server发送的Credential中设置一个是否需要认证的Flag。

Server在对Client认证成功之后,会把Authenticator中的Timestamp提出出来,通过SessionKey进行加密,当Client接收到并使用SessionKey进行解密之后,如果确认Timestamp和原来的完全一致,那么他可以认定Server正式他试图访问的Server。

那么为什么Server不直接把通过SessionKey进行加密的Authenticator原样发送给Client,而要把Timestamp提取出来加密发送给Client呢?

原因在于防止恶意的监听者通过获取的Client发送的Authenticator冒充Server获得Client的认证。

谈谈基于Kerberos的WindowsNetworkAuthentication-PartII

四、引入TicketGranting Service

通过上面的介绍,我们发现Kerberos实际上一个基于Ticket的认证方式。

Client想要获取Server端的资源,先得通过Server的认证;而认证的先决条件是Client向Server提供从KDC获得的一个有Server的MasterKey进行加密的SessionTicket(SessionKey+ClientInfo)。

可以这么说,SessionTicket是Client进入Server领域的一张门票。

而这张门票必须从一个合法的Ticket颁发机构获得,这个颁发机构就是Client和Server双方信任的KDC,同时这张Ticket具有超强的防伪标识:

它是被Server的MasterKey加密的。

对Client来说,获得SessionTicket是整个认证过程中最为关键的部分。

上面我们只是简单地从大体上说明了KDC向Client分发Ticket的过程,而真正在Kerberos中的TicketDistribution要复杂一些。

为了更好的说明整个TicketDistribution的过程,我在这里做一个类比。

现在的股事很火爆,上海基本上是全民炒股,我就举一个认股权证的例子。

有的上市公司在股票配股、增发、基金扩募、股份减持等情况会向公众发行认股权证,认股权证的持有人可以凭借这个权证认购一定数量的该公司股票,认股权证是一种具有看涨期权的金融衍生产品。

而我们今天所讲的Client获得Ticket的过程也和通过认股权证购买股票的过程类似。

如果我们把Client提供给Server进行认证的Ticket比作股票的话,那么Client在从KDC那边获得Ticket之前,需要先获得这个Ticket的认购权证,这个认购权证在Kerberos中被称为TGT:

TicketGrantingTicket,TGT的分发方仍然是KDC。

我们现在来看看Client是如何从KDC处获得TGT的:

首先Client向KDC发起对TGT的申请,申请的内容大致可以这样表示:

“我需要一张TGT用以申请获取用以访问所有Server的Ticket”。

KDC在收到该申请请求后,生成一个用于该Client和KDC进行安全通信的SessionKey(SKDC-Client)。

为了保证该SessionKey仅供该Client和自己使用,KDC使用Client的MasterKey和自己的MasterKey对生成的SessionKey进行加密,从而获得两个加密的SKDC-Client的Copy。

对于后者,随SKDC-Client一起被加密的还包含以后用于鉴定Client身份的关于Client的一些信息。

最后KDC将这两份Copy一并发送给Client。

这里有一点需要注意的是:

为了免去KDC对于基于不同Client的SessionKey进行维护的麻烦,就像Server不会保存SessionKey(SServer-Client)一样,KDC也不会去保存这个SessionKey(SKDC-Client),而选择完全靠Client自己提供的方式。

当Client收到KDC的两个加密数据包之后,先使用自己的MasterKey对第一个Copy进行解密,从而获得KDC和Client的SessionKey(SKDC-Client),并把该Session和TGT进行缓存。

有了SessionKey和TGT,Client自己的MasterKey将不再需要,因为此后Client可以使用SKDC-Client向KDC申请用以访问每个Server的Ticket,相对于Client的MasterKey这个Long-termKey,SKDC-Client是一个Short-termKey,安全保证得到更好的保障,这也是Kerberos多了这一步的关键所在。

同时需要注意的是SKDC-Client是一个SessionKey,他具有自己的生命周期,同时TGT和Session相互关联,当SessionKey过期,TGT也就宣告失效,此后Client不得不重新向KDC申请新的TGT,KDC将会生成一个不同SessionKey和与之关联的TGT。

同时,由于ClientLogoff也导致SKDC-Client的失效,所以SKDC-Client又被称为LogonSessionKey。

接下来,我们看看Client如何使用TGT来从KDC获得基于某个Server的Ticket。

在这里我要强调一下,Ticket是基于某个具体的Server的,而TGT则是和具体的Server无关的,Client可以使用一个TGT从KDC获得基于不同Server的Ticket。

我们言归正传,Client在获得自己和KDC的SessionKey(SKDC-Client)之后,生成自己的Authenticator以及所要访问的Server名称的并使用SKDC-Client进行加密。

随后连同TGT一并发送给KDC。

KDC使用自己的MasterKey对TGT进行解密,提取ClientInfo和SessionKey(SKDC-Client),然后使用这个SKDC-Client解密Authenticator获得ClientInfo,对两个ClientInfo进行比较进而验证对方的真实身份。

验证成功,生成一份基于Client所要访问的Server的Ticket给Client,这个过程就是我们第二节中介绍的一样了。

 

五、Kerberos的3个Sub-protocol:

整个Authentication

通过以上的介绍,我们基本上了解了整个Kerberosauthentication的整个流程:

整个流程大体上包含以下3个子过程:

1.Client向KDC申请TGT(TicketGrantingTicket)。

2.Client通过获得TGT向DKC申请用于访问Server的Ticket。

3.Client最终向为了Server对自己的认证向其提交Ticket。

不过上面的介绍离真正的KerberosAuthentication还是有一点出入。

Kerberos整个认证过程通过3个sub-protocol来完成。

这个3个Sub-Protocol分别完成上面列出的3个子过程。

这3个sub-protocol分别为:

1.AuthenticationServiceExchange

2.TicketGranting ServiceExchange

3.Client/ServerExchange

下图简单展示了完成这个3个Sub-protocol所进行MessageExchange。

1.AuthenticationServiceExchange

通过这个Sub-protocol,KDC(确切地说是KDC中的AuthenticationService)实现对Client身份的确认,并颁发给该Client一个TGT。

具体过程如下:

Client向KDC的AuthenticationService发送AuthenticationServiceRequest(KRB_AS_REQ),为了确保KRB_AS_REQ仅限于自己和KDC知道,Client使用自己的MasterKey对KRB_AS_REQ的主体部分进行加密(KDC可以通过Domain的AccountDatabase获得该Client的MasterKey)。

KRB_AS_REQ的大体包含以下的内容:

∙Pre-authenticationdata:

包含用以证明自己身份的信息。

说白了,就是证明自己知道自己声称的那个account的Password。

一般地,它的内容是一个被Client的Masterkey加密过的Timestamp。

∙Clientname&realm:

简单地说就是Domainname\Client

∙ServerName:

注意这里的ServerName并不是Client真正要访问的Server的名称,而我们也说了TGT是和Server无关的(Client只能使用Ticket,而不是TGT去访问Server)。

这里的ServerName实际上是KDC的TicketGrantingService的ServerName。

AS(AuthenticationService)通过它接收到的KRB_AS_REQ验证发送方的是否是在Clientname&realm中声称的那个人,也就是说要验证发送放是否知道Client的Password。

所以AS只需从AccountDatabase中提取Client对应的MasterKey对Pre-authenticationdata进行解密,如果是一个合法的Timestamp,则可以证明发送放提供的是正确无误的密码。

验证通过之

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1