文章目录
- 前提知识
- 原理
- 第一次对话
- 第二次对话
- 第三次对话
- 总结发现
前提知识
- KDC:由AS、TGS,还有一个Kerberos Database组成。
Kerberos Database用来存储用户的密码或者其他所有信息,请求的时候需要到数据库中查找。- AS:为客户端提供TGT票据,同时进行信息验证。
- TGT(Ticket Granting Tickets):一个信息票据,可以看做是一种入场票
- TGS(Ticket Granting Server) : 一个服务器,验证 TGT 与 Authenticator(密码证明信息),为客户端提供 Service Tickets(票证服务)。
- Kerberos Database:是一个数据库,当我们请求的时候会发送自己的用户ID/NAME,会来到数据库中查找是否存在…
- AS:为客户端提供TGT票据,同时进行信息验证。
Session表示会话,在kerberos中KDC会随机生成两种重要的会话钥匙:
- TGS Session Key
- 请求的服务 Server Session Key
原理
第一次对话
Client 发送信息包到AS中:(明文发送)
- 自身的 ID/NAME(用户名)
- 自身 IP地址
- 当前时间戳
上述信息发过去的时候全是明文,即我们发出去之前不进行信息加密
AS 收到后,首先去到数据库中查看是否有改用户名,存在才继续响应答复以下信息两种,在这个时候KDC随机生成了一个TGS Session Key一并发送过去
- 第一份信息包(用客户端密钥加密发送)
- 当前时间戳
- 客户端即将访问的 TGS 服务器的 NAME
- TGS 的有效时间(一般是八小时)
- TGS Session Key
上述↑↑↑第一份信息包使用客户端对应的密钥进行加密然后传输
(非明文传输,同时KDC拥有密码表,使用密码表与客户端进行身份认证)
- 第二份信息包(TGT票据):这一份就是 TGT(用TGS密钥加密发送)
- 客户端 NAME
- 客户端 IP
- 当前时间戳
- 客户端即将访问的 TGS 服务器的 NAME
- TGT 的有效时间(一般是八小时)
- TGS Session Key
上述↑↑↑第二份信息包使用TGS的个人密钥进行加密后传输
(这一份发过去后客户端无法解密,因为他不拥有TGS的密钥,所以这也说明了为什么后面客户端需要原封不断的将TGT发回来再次验证)
第二次对话
客户端收到了来自KDC发来的信息
首先客户端能够解密的信息包就只有第一份,因为是用客户端自己的密钥加密发过来的,所以解开后就能够获得里面的信息,其实主要是要获得TGS Session Key,客户端在第二次对话中需要通过该Key进行加密发送过去信息包
Client发送在本次发送的信息有三种
- 第一份信息包(明文发送)
- 发送客户端要访问的Service服务NAME/ID
- 第二份信息包(用我们解出来拿到的TGS Session Key 密钥加密发送)
- 客户端 NAME
- 客户端 IP
- 当前时间戳
- 第三份信息包(TGT原本就加密了)
- 原封不动的发送TGT票据回去
KDC收到信息包后首先使用自身密钥对TGT进行解密,他需要拿到里面的TGS Session Key,拿出来后将客户端的第二份信息包进行解密,拿到里面的客户端信息与当前收到的第一份信息包里面的客户端信息是否一致。
其中时间戳不是比较,而是通过客户端发送过来的时间,与我生成TGT时间相差是否超过可容忍的时间段,超过了就表示可能存在别修改的风险,就会考虑是否废弃掉本次对话以及废弃票据(有内鬼终止交易)
只有当所有信息都没有问题的时候才进行回应下一步操作:
在这个时候KDC又随机生成了一个客户端请求的服务 Server Session Key
- 第一份信息包(使用TGS Session Key密钥加密发送)
- 当前时间戳
- ticket ST票据的有效时间
- 请求的服务 Server Session Key
- 第二份信息包(ST票据)(使用请求的服务 Server自身的密钥加密发送)
- 客户端 NAME
- 客户端 IP
- 服务器的IP地址(认证服务器)
- ticket ST票据的有效时间
- 请求的服务 Server Session Key
(重点是这一份数据要发过去)
第三次对话
这时候客户端收到了TGS发来的最后一条数据,客户端使用之前缓存的TGS Session Key 对第一份信息包进行解密,最重要的是解密后拿到里面的请求的服务 Server Session Key密码,但是第二份信息包无法解密,是因为这是我们请求的Server的密钥加密的,我们无法得知。
这时候我们检查时间戳是否超时,无误就开始想最终Server发起最后的请求:
- 第一份信息包(使用请求的服务 Server Session Key密钥加密发送)
- 客户端 NAME
- 客户端 IP
- 当前时间戳
- ticket ST票据有效时间
- 第二份信息包(ST票据)
- 原封不动的发送我们无法解密的ST票据信息包
Server 收到客户端发来的信息包后,首先只能解密的只有用自己Server密钥对第二份信息包进行解密,主要是为了拿出ST票据里面的请求的服务Server Session Key,核对时间戳没有超时后,取出这一份密钥就可以解密第一份信息包,取出里面的客户端信息,然后再与我们解出来的ST票据里面的信息与之比较是否一致
信息核对没问题后开始确定身份了,服务端发送确认通信消息
- 第一份信息包(使用请求的服务 Server Session Key密钥加密发送)
- 请求的服务 NAME/ID
- 当前时间戳
客户端接收到信息包后,使用缓存下来的请求的服务 Server Session Key进行解密,解密出来必须要包含请求的服务 NAME/ID 和 时间戳,通过检查时间戳没有超市和正确的服务就表示认证成功了。然后再有效时间内都是使用Server Session Key进行双方的通讯。
总结发现
- 首先在其中生成的Session都是作下一次通话是否正确为目的,也就是为了保证认证过程双方身份都是正确的
- 除了客户端不知道KDC的密钥之外,我们在本地使用密钥加密发送过去KDC是知道如何解密的,利用这个特性,KDC就可以使用他自己内部的密钥进行信息加密作为票据,我们无法解密,但是我们发过去响应的时候总是带有时间戳或者客户端信息,我们票据中也带有这些信息,然而这些信息都是KDC才能解密, 所以票据就代表了对方发过来的信息是否有误,可以知道是否疑似超时被截获信息了。
- 在客户端主要是通过自身密钥获取会话的Session密钥,通过Session密钥就可以解密信息包了解到是否在传输过程中信息包被修改,或者发过来的信息包根本就不是KDC发来的。即使我们没有发现,那么黑客也也不会解密到我们的Session对话,即使解密了我们的Session密钥,时间也会超时,我们客户端很容易察觉该信息包不安全了。
- 由于所有的信息传输都没有在传输我们双方各自的密钥,所以黑客没有机会获取到我们的密钥,只要暴力破解,但是由于暴力破解需要时间,即使破解出来我们时间戳超时了也会将其丢弃信息包。
- 每一次的对话都是为下一次对话做准备,比如第二次KDC使用客户端请求的服务的那一个服务器的密钥进行加密发过去给客户端即:ST票据,客户端是无法解密的,需要他自己封装一份信息包,然后把ST也一起发过去给最后的Server,Server端用自己的密钥解密第二份信息包,然后与第一份客户端自己封装加密的信息包信息进行对比,确认无误就认证成功。
- 很容易发现这个过程中,每一次对话都会使用不同的密钥进行加密,并且产生会话密钥,同时含有时间戳,即使密钥被暴力破解了,也会超过对应的忍受时间,即会话时间结束额。kerberos认证系统总体还是很安全的,主要是要选择信任的KDC,如果我们的KDC被攻陷了,那就没办法了,裤衩都被骗走了。