Kerberos认证流程

第一步,账号A和KDC互相认证。

1、账号A利用哈希函数将密码转化成一把密钥,这里称它为Key-Client

2、利用Key-Client将当前的时间戳加密,生成一个字符串。表示为“{时间戳} Key-Client”

3、将上一步生成的字符串“{时间戳} Key-Client”、账号A的信息以及一段随机字符串发给KDC。这样就组成了Kerberos的身份认证请求AS-REQ,可以使用下面的公式来表示:

AS-REQ=“{时间戳} Key-Client”+“账号A的信息”+“随机字符串”。

4、KDC收到AS-REQ之后,读取到A的信息,就可以调出A的密码,再使用同样的哈希函数将其转化为Key-Client。有了Key-Client就可以解开“{时间戳} Key-Client”了。如果能够成功解开,就说明这个请求是由账号A生成的,毕竟其它账号不可能有Key-Client进行加密。

Kerberos之所以使用时间戳进行加密,原因就在于如果黑客在网络上截获了字符串“{时间戳} Key-Client”,那么就有可能伪装成账户A来欺骗认证。这种方式就称为重放攻击。采用这种攻击方式需要一定的时间,所以KDC把解密得到的时间戳和当前的时间作对比,如果二者的差异过大,那么就可以认为遭受到了重放攻击。假如采用与时间无关的字符进行加密,那么是无法避开重放攻击的,因此这就要求域中的所有计算机要在时间上同步。5、接下来,KDC需要向账号A证明自己的身份,刚才提到的随机字符串就需要用在这里。理论上KDC只要使用Key-Client加密随机字符串,再回复给账号A就可以证明自己的身份了。因为假的KDC是没有Key-Client的,那么账户A收到假的KDC的回复后,解不开那个随机字符串,就知道KDC是假的。

总结上面的流程,账号A和KDC都没有向对方发送密码,所以即便有一方是假的也不会导致信息的泄露。如果双方都是真的,则可以实现相互认证的过程。但是这个机制中的KDC是非常忙碌的,因为每次的认证都需要调出密码账号、进行哈希运算、实现解密操作……每个客户端一天可能会验证数十次,那么域中就需要配置大量的KDC才能够负担得起,因此改进流程就显得很有必要了。Kerberos在这里设计了一个比较巧妙的方法:

a.KDC生成两把一模一样的密钥Key-Client-KDC,用于以后账户A和KDC之间相互的认证,这样就省去了调出账号A的密码和哈希等的工作。按理说其中的一把Key-Client-KDC应当由账户A保管,另一把由KDC自己保管。但是KDC本来就很忙碌,额外再保管密钥会加重自身的负担,因此这个密钥就委托给账户A来保管,那么以后账户A需要KDC的时候,再把这个密钥还回来就可以了。但是这里面有一个问题,那就是如果有个假冒的账户A交回来一个假的密钥怎么办?为了避免这个问题,KDC把自己的密码哈希成Key-KDC,然后用它加密那把委托给账户A的密钥。Kerberos将这个密钥称为TGT(Ticket Granting Ticket),可以用以下公式表示:

TGT={账户A的相关信息,Key-Client-KDC} Key-KDC

有了这个委托保管的机制,那么KDC只需要记住自己的Key-KDC,就可以解开委托给所有账号的TGT,从而获得与该帐号之间的密钥。通过这个机制,KDC的工作负担就大大降低了。那么总结以上可以知道,KDC回复给账户A的AS-REP应当包括以下信息:

AS-REP=TGT,{ Key-Client-KDC,时间戳,随机字符串} Key-Client

b. 账户A收到AS-REP之后,利用Key-Client解密“{ Key-Client-KDC,时间戳,随机字符串} Key-Client”,通过解密得到的随机字符串和时间戳来确定KDC的真实性,然后把Key-Client-KDC和TGT保存起来备用。

第二步,账号A请KDC帮忙认证资源B。

1、现在应当把TGT交还给KDC,其次还有账户A的相关信息、当前时间戳以及要访问的资源B的信息。这个请求在Kerberos中被称为TGS-REQ,可以使用以下公式表示:

TGS-REQ=TGT,{账户A的相关信息,时间戳} Key-Client-KDC,“资源B的相关信息”

2、KDC收到TGS-REQ之后,先使用Key-KDC解密TGT得到Key-Client-KDC,再使用Key-Client-KDC解密出账号A的相关信息和时间戳来验证其身份。一旦认定账号A为真,那么接下来就要帮助A和B进行相互认证了。

3、KDC生成两把同样的密钥供A和B之间使用,我们就称这个密钥为Key-Client-Server。其中一把密钥直接交给账号A,另一把委托A转交给资源B。为了确保A不会受到假的资源B所骗,Kerberos把B的密码哈希成Key-Server,然后用它加密那把委托A转交给B的Key-Client-Server,成为一个只有真正的B才能够解密的ticket。总结以上,KDC给账号A的回复可以表示为:

Ticket={账号A的信息,Key-Client-Server} Key-Server

TGS-REP={ Key-Client-Server} Key-Client-KDC,ticket

这里的“账号A的信息”不单单包括A的名称,还包括A所在的域组(Domain Groups)。因此如果A属于很多个组(Groups),那么TGS-REP数据包就会很大。

4、账号A收到TGS-REP之后,首先使用Key-Client-KDC解开{ Key-Client-Server} Key-Client-KDC,从而得到Key-Client-Server。Ticket留下来发给资源B。接下来如果需要多次访问资源B,都可以使用同一个ticket,而不需要每次都向KDC申请,这就降低了KDC的负担。

第三步,账号A和资源B互相认证。

1、这时候,账号A给资源B发送“{账号A的信息,时间戳} Key-Client-Server”以及之前收到的ticket,这个请求称为AP-REQ:

AP-REQ=“{账号A的信息,时间戳} Key-Client-Server”,ticket

2、如果资源B是假的,那么它就解不开ticket。如果资源B是真的,它可以用自己的密码生成Key-Server来解开ticket,从而得到Key-Client-Server。有了Key-Client-Server就可以解开“{账号A的信息,时间戳} Key-Client-Server”部分。这样资源B就可以确定账号A为真,然后回复AP-REP来证明自己也是真的:

AP-REP={时间戳} Key-Client-Server

3、账号A利用Key-Client-Server来解密AP-REP,再通过得到的时间戳来判断对方是否为真。

转自:https://fly8wo.github.io/2018/09/23/%E7%BD%91%E7%BB%9C%E6%95%B0%E6%8D%AE%E5%8C%85%E5%88%86%E6%9E%90%E4%B9%8BKerberos/

posted @ 2023-03-23 15:16  車輪の唄  阅读(148)  评论(0编辑  收藏  举报  来源