《转》谈谈基于Kerberos的Windows Network Authentication
http://www.cnblogs.com/artech/archive/2007/07/05/807492.html
基本原理
引入Key Distribution: KServer-Client从何而来
引入Authenticator : 为有效的证明自己提供证据
引入Ticket Granting Service:如何获得Ticket
Kerberos的3个Sub-protocol:整个Authentication的流程
User2User Protocol: 有效地保障Server的安全
Kerberos的优点的优点
前几天在给人解释Windows是如何通过
Kerberos进行Authentication的时候,讲了半天也别把那位老兄讲明白,还差点把自己给绕进去。后来想想原因有以下两点:对于一个没有
完全不了解Kerberos的人来说,Kerberos的整个Authentication过程确实不好理解——一会儿以这个Key进行加密、一会儿又要
以另一个Key进行加密,确实很容易把人给弄晕;另一方面是我讲解方式有问题,一开始就从Kerberos的3个Sub-protocol全面讲述整个
Authentication
过程,对于一个完全不了解Kerberos的人来说要求也忒高了点。为此,我花了一些时间写了这篇文章,尽量以由浅入深、层层深入的方式讲述我所理解的基
于Kerberos的Windows Network
Authentication,希望这篇文章能帮助那些对Kerberos不明就里的人带来一丝帮助。对于一些不对的地方,欢迎大家批评指正。
一、 基本原理
Authentication解决的是“如何证
明某个人确确实实就是他或她所声称的那个人”的问题。对于如何进行Authentication,我们采用这样的方法:如果一个秘密(secret)仅仅
存在于A和B,那么有个人对B声称自己就是A,B通过让A提供这个秘密来证明这个人就是他或她所声称的A。这个过程实际上涉及到3个重要的关于
Authentication的方面:
- Secret如何表示。
- A如何向B提供Secret。
- B如何识别Secret。
基于这3个方面,我们把Kerberos Authentication进行最大限度的简化:整个过程涉及到Client和Server,他们之间的这个Secret我们用一个Key(KServer-Client)来表示。Client为了让Server对自己进行有效的认证,向对方提供如下两组信息:
- 代表Client自身Identity的信息,为了简便,它以明文的形式传递。
- 将Client的Identity使用KServer-Client作为Public Key、并采用对称加密算法进行加密。
由于KServer-Client仅仅被Client和Server知晓,所以被Client使用KServer-Client加密过的Client Identity只能被Client和Server解密。同理,Server接收到Client传送的这两组信息,先通过KServer-Client对后者进行解密,随后将机密的数据同前者进行比较,如果完全一样,则可以证明Client能过提供正确的KServer-Client,而这个世界上,仅仅只有真正的Client和自己知道KServer-Client,所以可以对方就是他所声称的那个人。
Keberos大体上就是按照这样的一个原理来进行Authentication的。但是Kerberos远比这个复杂,我将在后续的章节中不断地扩充这个过程,知道Kerberos真实的认证过程。为了使读者更加容易理解后续的部分,在这里我们先给出两个重要的概念:
- Long-term Key/Master Key:
在Security的领域中,有的Key可能长期内保持不变,比如你在密码,可能几年都不曾改变,这样的Key、以及由此派生的Key被称为Long-
term Key。对于Long-term Key的使用有这样的原则:被Long-term
Key加密的数据不应该在网络上传输。原因很简单,一旦这些被Long-term
Key加密的数据包被恶意的网络监听者截获,在原则上,只要有充足的时间,他是可以通过计算获得你用于加密的Long-term
Key的——任何加密算法都不可能做到绝对保密。
在一般情况下,对于一个Account来说,密
码往往仅仅限于该Account的所有者知晓,甚至对于任何Domain的Administrator,密码仍然应该是保密的。但是密码却又是证明身份的
凭据,所以必须通过基于你密码的派生的信息来证明用户的真实身份,在这种情况下,一般将你的密码进行Hash运算得到一个Hash code,
我们一般管这样的Hash Code叫做Master Key。由于Hash Algorithm是不可逆的,同时保证密码和Master
Key是一一对应的,这样既保证了你密码的保密性,有同时保证你的Master Key和密码本身在证明你身份的时候具有相同的效力。
- Short-term Key/Session Key:
由于被Long-term Key加密的数据包不能用于网络传送,所以我们使用另一种Short-term
Key来加密需要进行网络传输的数据。由于这种Key只在一段时间内有效,即使被加密的数据包被黑客截获,等他把Key计算出来的时候,这个Key早就已
经过期了。
二、引入Key Distribution: KServer-Client从何而来
上面我们讨论了Kerberos Authentication的基本原理:通过让被认证的一方提供一个仅限于他和认证方知晓的Key来鉴定对方的真实身份。而被这个Key加密的数据包需要在Client和Server之间传送,所以这个Key不能是一个Long-term Key,而只可能是Short-term Key,这个可以仅仅在Client和Server的一个Session中有效,所以我们称这个Key为Client和Server之间的Session Key(SServer-Client)。
现在我们来讨论Client和Server如何得到这个SServer-Client。在这里我们要引入一个重要的角色:Kerberos Distribution Center-KDC。
KDC在整个Kerberos
Authentication中作为Client和Server共同信任的第三方起着重要的作用,而Kerberos的认证过程就是通过这3方协作完成。
顺便说一下,Kerberos起源于希腊神话,是一支守护着冥界长着3个头颅的神犬,在keberos
Authentication中,Kerberos的3个头颅代表中认证过程中涉及的3方:Client、Server和KDC。
对于一个Windows Domain来说,Domain Controller扮演着KDC的角色。KDC维护着一个存储着该Domain中所有帐户的Account Database(一般地,这个Account Database由AD来维护),也就是说,他知道属于每个Account的名称和派生于该Account Password的Master Key。而用于Client和Server相互认证的SServer-Client就是有KDC分发。下面我们来看看KDC分发SServer-Client的过程。
通过下图我们可以看到KDC分发SServer-Client的简单的过程:首先Client向KDC发送一个对SServer-Client的申请。这个申请的内容可以简单概括为“我是某个Client,我需要一个Session Key用于访问某个Server
”。KDC在接收到这个请求的时候,生成一个Session Key,为了保证这个Session
Key仅仅限于发送请求的Client和他希望访问的Server知晓,KDC会为这个Session
Key生成两个Copy,分别被Client和Server使用。然后从Account
database中提取Client和Server的Master Key分别对这两个Copy进行对称加密。对于后者,和Session
Key一起被加密的还包含关于Client的一些信息。
KDC现在有了两个分别被Client和
Server 的Master Key加密过的Session Key,这两个Session
Key如何分别被Client和Server获得呢?也许你
马上会说,KDC直接将这两个加密过的包发送给Client和Server不就可以了吗,但是如果这样做,对于Server来说会出现下面 两个问题:
- 由于一个Server会面对若干不同的Client, 而每个Client都具有一个不同的Session Key。那么Server就会为所有的Client维护这样一个Session Key的列表,这样做对于Server来说是比较麻烦而低效的。
- 由于网络传输的不确定性,可能出现
这样一种情况:Client很快获得Session Key,并将这个Session
Key作为Credential随同访问请求发送到Server,但是用于Server的Session
Key确还没有收到,并且很有可能承载这个Session Key的永远也到不了Server端,Client将永远得不到认证。
为了解决这个问题,Kerberos的做法很简单,将这两个被加密的Copy一并发送给Client,属于Server的那份由Client发送给Server。
可
能有人会问,KDC并没有真正去认证这个发送请求的Client是否真的就是那个他所声称的那个人,就把Session
Key发送给他,会不会有什么问题?如果另一个人(比如Client B)声称自己是Client A,他同样会得到Client
A和Server的Session Key,这会不会有什么问题?实际上不存在问题,因为Client B声称自己是Client
A,KDC就会使用Client A的Password派生的Master Key对Session Key进行加密,所以真正知道Client A
的Password的一方才会通过解密获得Session Key。
三、引入Authenticator - 为有效的证明自己提供证据
通过上面的过程,Client实际上获得了两组
信息:一个通过自己Master Key加密的Session Key,另一个被Sever的Master Key加密的数据包,包含Session
Key和关于自己的一些确认信息。通过第一节,我们说只要通过一个双方知晓的Key就可以对对方进行有效的认证,但是在一个网络的环境中,这种简单的做法
是具有安全漏洞,为此,Client需要提供更多的证明信息,我们把这种证明信息称为Authenticator,在Kerberos的Authenticator实际上就是关于Client的一些信息和当前时间的一个Timestamp(关于这个安全漏洞和Timestamp的作用,我将在后面解释)。
在这个基础上,我们再来看看Server如何对Client进行认证:Client通过自己的Master Key对KDC加密的Session Key进行解密从而获得Session Key,随后创建Authenticator(Client Info + Timestamp)并用Session Key对其加密。最后连同从KDC获得的、被Server的Master Key加密过的数据包(Client Info + Session Key)一并发送到Server端。我们把通过Server的Master Key加密过的数据包称为Session Ticket。
当Server接收到这两组数据后,先使用他自己的Master Key对Session Ticket进行解密,从而获得Session Key。随后使用该Session Key解密Authenticator,通过比较Authenticator中的Client Info和Session Ticket中的Client Info从而实现对Client的认证。
为什么要使用Timestamp?
到这里,很多人可能认为这样的认证过程天衣无缝:只有当Client提供正确的Session Key方能得到Server的认证。但是在现实环境中,这存在很大的安全漏洞。
我们试想这样的现象:Client向
Server发送的数据包被某个恶意网络监听者截获,该监听者随后将数据包座位自己的Credential冒充该Client对Server进行访问,在
这种情况下,依然可以很顺利地获得Server的成功认证。为了解决这个问题,Client在Authenticator中会加入一个当前时间的Timestamp。
在Server对Authenticator中的Client Info和Session Ticket中的Client Info进行比较之前,会先提取Authenticator中的Timestamp,并同当前的时间进行比较,如果他们之间的偏差超出一个可以接受的时间范围(一般是5mins),Server会直接拒绝该Client的请求。在这里需要知道的是,Server维护着一个列表,这个列表记录着在这个可接受的时间范围内所有进行认证的Client和认证的时间。对于时间偏差在这个可接受的范围中的Client,Server会从这个这个列表中获得最近一个该Client的认证时间,只有当Authenticator中的Timestamp晚于通过一个Client的最近的认证时间的情况下,Server采用进行后续的认证流程。
Time Synchronization的重要性
上述 基于Timestamp的认证机制只有在Client和Server端的时间保持同步的情况才有意义。所以保持Time Synchronization在整个认证过程中显得尤为重要。在一个Domain中,一般通过访问同一个Time Service获得当前时间的方式来实现时间的同步。
双向认证(Mutual Authentication)
Kerberos一个重要的优势在于它能够提供双向认证:不但Server可以对Client 进行认证,Client也能对Server进行认证。
具体过程是这样的,如果Client需要对他访
问的Server进行认证,会在它向Server发送的Credential中设置一个是否需要认证的Flag。Server在对Client认证成功之
后,会把Authenticator中的Timestamp提出出来,通过Session Key进行加密,当Client接收到并使用Session
Key进行解密之后,如果确认Timestamp和原来的完全一致,那么他可以认定Server正式他试图访问的Server。
那么为什么Server不直接把通过
Session
Key进行加密的Authenticator原样发送给Client,而要把Timestamp提取出来加密发送给Client呢?原因在于防止恶意的监
听者通过获取的Client发送的Authenticator冒充Server获得Client的认证。
谈谈基于Kerberos的Windows Network Authentication - Part II
相关内容:
《转》谈谈基于Kerberos的Windows Network Authentication的更多相关文章
- 谈谈基于OAuth 2.0的第三方认证 [下篇]
从安全的角度来讲,<中篇>介绍的Implicit类型的Authorization Grant存在这样的两个问题:其一,授权服务器没有对客户端应用进行认证,因为获取Access Token的 ...
- 谈谈基于OAuth 2.0的第三方认证 [上篇]
对于目前大部分Web应用来说,用户认证基本上都由应用自身来完成.具体来说,Web应用利用自身存储的用户凭证(基本上是用户名/密码)与用户提供的凭证进行比较进而确认其真实身份.但是这种由Web应用全权负 ...
- 谈谈基于OAuth 2.0的第三方认证 [中篇]
虽然我们在<上篇>分别讨论了4种预定义的Authorization Grant类型以及它们各自的适用场景的获取Access Token的方式,我想很多之前没有接触过OAuth 2.0的读者 ...
- Kerberos认证原理及基于Kerberos认证的NFS文件共享
目录 Kerberos认证原理 简介 client访问server过程 一.Authentication Service Exchange (AS Exchange) 二.Ticket Grantin ...
- 基于EasyUI实现windows桌面
之前为大家介绍了 基于jquery tool实现的windows桌面效果,今天给大家带来一款基于EasyUI实现windows桌面.这款桌面适用浏览器:360.FireFox.Chrome.Safar ...
- C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载(极速,简洁)
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- 用Visual C#开发基于OpenCV的Windows应用程序
http://blog.163.com/wangxh_jy/blog/static/28233883201001581640283/ 关于详细的配置及程序运行截图,请下载:http://downloa ...
- 在 Linux 客户端配置基于 Kerberos 身份验证的 NFS 服务器
在这篇文章中我们会介绍配置基于 Kerberos 身份验证的 NFS 共享的整个流程.假设你已经配置好了一个 NFS 服务器和一个客户端.如果还没有,可以参考 安装和配置 NFS 服务器[2] - 它 ...
- Creating Dialogbased Windows Application (4) / 创建基于对话框的Windows应用程序(四)Edit Control、Combo Box的应用、Unicode转ANSI、Open File Dialog、文件读取、可变参数、文本框自动滚动 / VC++, Windows
创建基于对话框的Windows应用程序(四)—— Edit Control.Combo Box的应用.Unicode转ANSI.Open File Dialog.文件读取.可变参数.自动滚动 之前的介 ...
随机推荐
- [bzoj1146]网络管理
发现是链上的问题,所以树链剖分发现要查询第k大,因为第k大不支持合并,所以要二分答案二分答案后相当于询问一些区间内大于某数的数个数,直接线段树套平衡树即可时间复杂度$o(nlog^{4}_n)$(跟$ ...
- (前端)面试300问之(2)CSS元素居中【水平、垂直、2者同时居中】
一 仅水平居中 1 行内元素 1)给父元素添加 text-align:center 即可 <div class="parent"> <span class=&qu ...
- 当 dotnet-monitor 遇上 Prometheus, 是种什么样的体验?
对于开发和运维人员来说, 监控大屏很棒, 让我们来做一个 Dashboard 吧! 大家可能听说过一些 CLI 诊断工具, 比如 dotnet-counters,dotnet-dump 和 dotne ...
- JS设计模式之建造者模式
建造者模式(builder pattern)属于创建型模式的一种,提供一种创建复杂对象的方式.它将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式是一步一步的创建 ...
- 如何构建自己的KEGG数据库
本文转自Y叔公众号 自己KEGG数据库好处: 可重复性好 没网也可以进行分析 步骤 1 在KEGG官网找到自己物种的3字符缩写 2 加载Y叔获取kegg.db 的R包 1 ##安装Y叔的包 2 lib ...
- Oracle-where exists()、not exists() 、in()、not in()用法以及效率差异
0.exists() 用法: select * from T1 where exists(select 1 from T2 where T1.a=T2.a) 其中 "select 1 fro ...
- linux下vi与vim区别以及vim的使用-------vim编辑时脚本高光显示语法
vi与vimvi编辑器是所有Unix及Linux系统下标准的编辑器,他就相当于windows系统中的记事本一样,它的强大不逊色于任何最新的文本编辑器.他是我们使用Linux系统不能缺少的工具.由于对U ...
- 《手把手教你》系列技巧篇(四十六)-java+ selenium自动化测试-web页面定位toast-下篇(详解教程)
1.简介 终于经过宏哥的不懈努力,偶然发现了一个toast的web页面,所以直接就用这个页面来夯实一下,上一篇学过的知识-处理toast元素. 2.安居客 事先声明啊,宏哥没有收他们的广告费啊,纯粹是 ...
- SpringBoot 整合 MyBatis,实现 CRUD 示例
目录 前言 创建项目/模块 SpringBoot Console Application CommandLineRunner SpringBoot 集成 MyBatis 创建数据库/表 配置数据源/连 ...
- .NET Core基础篇之:集成Swagger文档与自定义Swagger UI
Swagger大家都不陌生,Swagger (OpenAPI) 是一个与编程语言无关的接口规范,用于描述项目中的 REST API.它的出现主要是节约了开发人员编写接口文档的时间,可以根据项目中的注释 ...