该协议涉及的攻击手段如下
image.png
理解协议过程所画的草稿图
aa84c82a24cfea51641782fb3471b4e.jpg
鉴于我画的图丑晕了,于是在笔记中还是使用别人的图吧

未引入TGS前的认证流程

image.png
客户端向KDC发起对sessionkey的请求,KDC使用数据库中存储的该客户端的密码对sessionkey进行加密,同时向客户端请求的服务器发送同样的sessionkey,但使用服务器端的密码进行加密,然后客户端再使用sessionkey向服务器进行认证

在这个流程中我们可以发现一些问题
1.A向KDC申请sessionkey,KDC同时向A和B发送sessionkey,如果由于网络等原因导致B在A向它请求认证时还没有收到sessionkey就会导致认证失败,所以可以尝试在返回给A使用client password加密的sessionkey的时候将本该发给B的信息一同发送给A,再由A向B请求验证的时候一同发送给B
2.A提出SessionKey的申请时,KDC凭什么就生成了SessionKey给了A,也就是说,KDC缺乏对A的认证,所以在分发SessionKey之前,KDC需要增加对A的认证,解决办法就是,将KDC机构分成两部分:

AS:Authentication Service,用于KDC对A的认证
TGS:Ticket Granting Service,用于KDC向A和B分发Session Key

引入TGS后的认证流程

image.png
这个图也就很好的表明了将KDC分为AS和TGS后的作用,也就解决了刚才未引入TGS前我们提出的问题1和2,对于2的解决是只有当确认了A的身份后,才会给sessionkey(a-b)

总体来说就是当client想要访问server上的某个服务时,需要先向AS证明自己的身份,验证通过后AS会发放一个TGT,client会再次向TGS证明自己的身份后,TGS会发放一个ST,随后client向server发起认证请求

详细认证过程

image.png
①:KRB_AS_REQ:Client-A发送Authenticator向KDC的AS服务认证自己的身份(通过提供自身密码加密的一个时间戳TimeStamp)

②:KRB_AS_REP:AS通过KDC数据库中存储的Client-A密码的副本,解密收到的Authenticator,如果解密出的TimeStamp符合要求,则AS服务认为Client-A就是所谓的Client-A。认证成功后,AS服务生成一个短期有效的SessionKeya-kdc,将该Key使用A的密码副本加密成密文1,另外将Key连同时间戳标志(控制该SessionKey的有效时间)通过TGS服务的密码也就是KDC的密码加密为密文2(称为TGT),将这两个密文组合成KRB_AS_REP返回给Client-A

③:KRB_TGS_REQ:Client-A在接收到KRB_AS_REP后,首先使用自身密码解密密文1得到SessionKeya-kdc,此时需要注意的是,密文2(TGT)是被KDC的密码加密的,所以Client-A无法解密,这也是Kerberos协议设计的精妙之处,既解决了Server端(TGS相对于Client-A也称之为Server端)无法及时接收SessionKey的问题,又不怕Client-A对该TGT的伪造,因为Client-A不知道Server端的密码

得到SessionKeya-kdc后,Client-A利用其加密时间戳生成Authenticator用于向TGS申请Client-A与Client-B进行认证所需的SessionKeya-b,连同刚才KRB_AS_REP接收的TGT一同组合成KRB_TGS_REQ发送给TGS

④:KRB_TGS_REP:TGS在接收到KRB_TGS_REQ之后,利用KDC密码解密TGT获得本来就该发送给自己的SessionKeya-kdc,然后用其解密KRB_TGS_REQ中的Authenticator得到Client-A发送过来的时间戳,如果时间戳符合要求,则生成一个短期有效的SessionKeya-b,注意此时利用SessionKeya-kdc将SessionKeya-b加密为密文1,然后利用Server-B的密码将SessionKeya-b加密为密文2(称为ServiceTicket),两个密文一同构成KRB_TGS_REP返回给Client-A

⑤:KRB_AP_REQ:Client-A在接收到KRB_TGS_REP之后,首先使用缓存的SessionKeya-kdc将密文1中的SessionKeya-b解密出来,然后利用其加密时间戳生成Authenticator用于向B进行对自身的验证,另外,和刚才TGT一样,密文2也就是ServiceTicket是用Server-B的密码加密的,所以Client-A无法解密,也就无法伪造,这也同样解决了在三方认证中作为Server端的B无法及时接收SessionKey的问题,又不怕Client-A对ServiceTicket的伪造

⑥:KRB_AP_REP:Server-B受到KRB_AP_REQ之后,利用自身密码解密ServiceTicket,得到SessionKeya-b,然后用SessionKeya-b解密Authenticator得到时间戳,验证A的身份