Kerberos 身份验证

简介

Kerberos 是一种由 MIT(麻省理工大学)提出的一种基于加密 Ticket 的身份认证协议。它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证,用于验证用户或主机的标识。。

适用范围:Windows Server 2022、Windows Server 2019、Windows Server 2016

在 Kerberos 协议中主要是有三个角色的存在:

1、访问服务的 Client;

2、提供服务的 Server;

3、KDC(Key Distribution Center)密钥分发中心(其中包含了The Authentication Server 和 The Ticket Granting Server)

  • Key Distribution Center(即 KDC), 是 Kerberos 的核心组件,主要由三个部分组成:
    1. Kerberos Database: 包含了一个 Realm 中所有的 principal、密码与其他信息。(默认:Berkeley DB)
    2. Authentication Service(AS): 进行用户信息认证,为客户端提供 Ticket Granting Tickets(TGT)。
    3. Ticket Granting Service(TGS): 验证 TGT 与 Authenticator,为客户端提供 Service Tickets
      在这里插入图片描述

Kerberos认证流程

简化版

客户端在访问每个想要访问的网络服务时,他需要携带一个专门用于访问该服务并且能够证明自己身份的票据,当服务端收到了该票据他才能认定客户端身份正确,向客户端提供服务。所以整个认证流程可简化为两大步:

  1. 客户端向KDC请求获取想要访问的目标服务的服务授予票据(Ticket);
  2. 客户端拿着从KDC获取的服务授予票据(Ticket)访问相应的网络服务;
    在这里插入图片描述
    在这里插入图片描述

详细版

上面说到了简化版的Kerberos认证流程,大致的过程确实可以看作这两步,但其中还存在一些问题:

  1. KDC怎么知道你(客户端)就是真正的客户端?凭什么给你发放服务授予票据(Ticket)呢?
  2. 服务端怎么知道你带来的服务授予票据(Ticket)就是一张真正的票据呢?

所以这就需要详细说一下Kerberos 详细认证流程了。所以整个Kerberos认证流程可以细化为三个阶段也可以理解为三次通信:

  1. Client 与 AS 的交互,
  2. Client 与 TGS 的交互,
  3. Client 与 Server 的交互。

第一次通信Client 与 AS 的交互

  1. 客户端用户向KDC以明文的方式发起请求。该次请求中携带了自己的用户名,主机IP,和当前时间戳;

  2. KDC当中的AS(Authentication Server)接收请求(AS是KDC中专门用来认证客户端身份的认证服务器)后去kerberos认证数据库中根据用户名查找是否存在该用户,此时只会查找是否有相同用户名的用户,并不会判断身份的可靠性;

  3. 如果没有该用户名,认证失败,服务结束;如果存在该用户名,则AS认证中心便认为用户存在,此时便会返回响应给客户端,其中包含两部分内容:

    第一部分内容称为TGT,他叫做票据授予票据,客户端需要使用TGT去KDC中的TGS(票据授予中心)获取访问网络服务所需的Ticket(服务授予票据),TGT中包含的内容有kerberos数据库中存在的该客户端的Name,IP,当前时间戳,客户端
    即将访问的TGS的Name,TGT的有效时间以及一把用于客户端和TGS间进行通信的Session_key(CT_SK)。整个TGT使用TGS密钥加密,客户端是解密不了的,由于密钥从没有在网络中传输过,所以也不存在密钥被劫持破解的情况。

    第二部分内容是使用客户端密钥加密的一段内容,其中包括用于客户端和TGS间通信的Session_key(CT_SK),客户端即将访问的TGS的Name以及TGT的有效时间,和一个当前时间戳。该部分内容使用客户端密钥加密,所以客户端在拿到该部分内容时可以通过自己的密钥解密。如果是一个假的客户端,那么他是不会拥有真正客户端的密钥的,因为该密钥也从没在网络中进行传输过。这也同时认证了客户端的身份,如果是假客户端会由于解密失败从而终端认证流程。
    至此,第一次通信完成。

在这里插入图片描述

第二次通信Client 与 TGS 的交互

客户端行为:

  1. 客户端使用CT_SK加密将自己的客户端信息发送给KDC,其中包括客户端名,IP,时间戳;
  2. 客户端将自己想要访问的Server服务以明文的方式发送给KDC;
  3. 客户端将使用TGS密钥加密的TGT也原封不动的也携带给KDC;

TGS行为:

  1. 此时KDC中的TGS(票据授予服务器)收到了来自客户端的请求。他首先根据客户端明文传输过来的Server服务IP查看当前kerberos系统中是否存在可以被用户访问的该服务。如果不存在,认证失败结束,。如果存在,继续接下来的认证。

  2. TGS使用自己的密钥将TGT中的内容进行解密,此时他看到了经过AS认证过后并记录的用户信息,一把Session_KEY即CT_SK,还有时间戳信息,他会现根据时间戳判断此次通信是否真是可靠有无超出时延。

  3. 如果时延正常,则TGS会使用CK_SK对客户端的第一部分内容进行解密(使用CT_SK加密的客户端信息),取出其中的用户信息和TGT中的用户信息进行比对,如果全部相同则认为客户端身份正确,方可继续进行下一步。

  4. 此时KDC将返回响应给客户端,响应内容包括:

    第一部分:用于客户端访问网络服务的使用Server密码加密的ST(Servre Ticket),其中包括客户端的Name,IP,需要访问的网络服务的地址Server IP,ST的有效时间,时间戳以及用于客户端和服务端之间通信的CS_SK(Session Key)。

    第二部分:使用CT_SK加密的内容,其中包括CS_SK和时间戳,还有ST的有效时间。由于在第一次通信的过程中,AS已将CT_SK通过客户端密码加密交给了客户端,且客户端解密并缓存了CT_SK,所以该部分内容在客户端接收到时是可以自己解密的。
    至此,第二次通信完成。

在这里插入图片描述

第三次通信 Client 与 Server 的交互

客户端:

  1. 客户端使用CK_SK将自己的主机信息和时间戳进行加密作为交给服务端的第一部分内容,然后将ST(服务授予票据)作为第二部分内容都发送给服务端。

服务端:

  1. 服务器此时收到了来自客户端的请求,他会使用自己的密钥,即Server密钥将客户端第二部分内容进行解密,核对时间戳之后将其中的CS_SK取出,使用CS_SK将客户端发来的第一部分内容进行解密,从而获得经过TGS认证过后的客户端信息,此时他将这部分信息和客户端第二部分内容带来的自己的信息进行比对,最终确认该客户端就是经过了KDC认证的具有真实身份的客户端,是他可以提供服务的客户端。此时服务端返回一段使用CT_SK加密的表示接收请求的响应给客户端,在客户端收到请求之后,使用缓存在本地的CS_ST解密之后也确定了服务端的身份(其实服务端在通信的过程中还会使用数字证书证明自己身份)。

至此,第三次通信完成。此时也代表着整个kerberos认证的完成,通信的双方都确认了对方的身份,此时便可以放心的进行整个网络通信了。在这里插入图片描述

1、AS-REQ
域内⽤户访问域中的服务,输⼊⽤户名和密码,本机的Kerberos服务会向KDC的AS认证服务 发送AS-REQ认证请求。

  • 请求包:⽤户名、主机名、加密类型 和 Authenticator以及⼀些其他信息。

2、AS-REP
KDC接收到请求之后,通过AD活动⽬录查询得到该⽤户的密码Hash,⽤该密码Hash对请求 包的Authenticator进⾏解密,如果解密成功,则证明请求者提供的密码正确,⽽且需要时间戳 范围在五分钟内,于是预认证成功,校验时间是为了防⽌重放。响应包:TGT 和 ⽤户NTLM-Hash加密的Login Session key以及⼀些其他信息以及PAC。 Login Session key ⽤于在下阶段的交互中的数据加密。
3、TGS-REQ 客户端向KDC申请针对指定服务的ST服务票据请求。
请求包:客户端信息、authenticator、TGT认购凭证和访问的服务名以及⼀些其他信息。info + authenticator(login session key(timestamp)) + TGT + service name
4、TGS-REP
TGS接收到请求之后,检查⾃身是否存在客户端所请求的服务。如果服务存在,使⽤ krbtgt_NTLM Hash解密TGT获取Login Session Key,然后通过Login Session Key解密 Authenticator, 若解密成功,则验证了客户端身份,同时还会验证时问戳是否合法,防⽌重 放。并且还会检查TGT中的时间戳是否过期,原始地址是否和TGT中保存的地址相同,这⾥的 地址主要指的是主机名。
如果验证通过,KDC会⽣成⼀个⽤Logon Session Key加密后的⽤于确保客户端-服务器之间 通信安全的ServiceSession Key会话秘钥。并且会为该客户端⽣成ST服务票据。 ST:响应包:
5、AP-REQ
客户端接收到TGS回复后,通过步骤2中Login Session Key解密得到原始Service Session Key,同时它也拿到了ST(Service Ticket)服务票据。该Serivce Session Key 和 ST服务票据 会 被客户端缓存。
请求包(请求对象为业务服务器):authenticator + ST
6、AP-REP
服务器在接收到请求之后,先通过该服务的NTLM Hash哈希解密ST服务票据,并从中提取 Service Session Key。然后通过提取出来的Service Session Key 解密Authenticator,进⽽验 证了客户端的真实身份。
验证了客户端的身份后,服务端使⽤PAC发送给KDC验证该⽤户的权限。KDC通过SID判断⽤ 户的⽤户组信息,⽤户权限,最终将结果返回给服务端。最终客户端根据KDC的验证结果进 ⾏访问服务。
双向验证 :访问者和被访问者互相验证对⽅的身份。客户端验证服务器–服务端⽤ Service Session Key加密时问戳作为Authenticator,发送给客户端。客户端使⽤ Service Session Key解密authenticator,如果解密成功,则可以验证服务器的合法 性。双向认证过后,开始了服务资源的访问。
linkes:https://seevae.github.io/2020/09/12/%E8%AF%A6%E8%A7%A3kerberos%E8%AE%A4%E8%AF%81%E6%B5%81%E7%A8%8B/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Java API中实现ES的Kerberos身份验证,可以按照以下步骤进行操作: 1.启用Kerberos认证:在ES的配置文件中,将xpack.security.authc.realms.kerberos.enabled设置为true,并设置其他相关的Kerberos配置参数,如krb5.conf和jaas.conf文件的路径等。 2.在Java代码中创建Kerberos认证的TransportClient:可以使用TransportClient.Builder类来创建Kerberos认证的TransportClient,并设置相应的Kerberos认证参数。 3.使用Kerberos认证的TransportClient进行ES操作:使用TransportClient进行ES操作时,可以通过调用prepareSearch()、prepareIndex()等方法来创建相应的SearchRequest、IndexRequest等请求对象,并使用Kerberos认证的TransportClient来执行这些请求。 以下是一个使用Java API实现ES的Kerberos身份验证的示例代码: ``` import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import java.net.InetAddress; import java.util.concurrent.ExecutionException; public class KerberosAuthExample { public static void main(String[] args) throws ExecutionException, InterruptedException { //设置Kerberos认证相关参数 System.setProperty("java.security.auth.login.config", "/path/to/jaas.conf"); System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); System.setProperty("sun.security.krb5.debug", "true"); //创建Kerberos认证的TransportClient TransportClient client = new PreBuiltTransportClient(Settings.builder() .put("xpack.security.user", "elastic:password") .put("cluster.name", "my-cluster") .put("xpack.security.authc.realms.kerberos.type", "kerberos") .put("xpack.security.authc.realms.kerberos.order", "0") .put("xpack.security.authc.realms.kerberos.acceptor_principal", "HTTP/[email protected]") .put("xpack.security.authc.realms.kerberos.keytab.path", "/path/to/keytab") .build()) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300)); //使用Kerberos认证的TransportClient进行ES操作 client.prepareSearch("my-index") .setQuery(QueryBuilders.matchAllQuery()) .setSize(10) .get(); //关闭TransportClient client.close(); } } ``` 注意:以上示例代码仅供参考,实际使用时需要根据具体情况进行修改。另外,Kerberos身份验证需要配置KDC和相关的Kerberos文件,具体操作请参考相关文档或向相关人员咨询。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kuokay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值