• Kerberos是一个重要的认证协议,它为互不相识的通信双方做安全的认证工作。Kerberos这个名字的原义是希腊神话中守卫冥王大门的长有三头的看门狗。下面这篇Kerberos的文章不知是哪位老大翻译的,感谢先!

    这是MIT(Massachusetts Institute of Technology)为了帮助人们理解Kerberos的原理而写的一篇对话集。里面有两个虚构的人物:Athena和Euripides,通过Athena不断的构思和Euripides不断的寻找其中的漏洞,使大家明白了Kerberos协议的原理。
      Athena: 雅典娜,智慧与技艺的女神。
      Euripides:欧里庇得斯, 希腊的悲剧诗人。
    译文如下:
    第一幕
    在一个小工作间里。Athena和Euripides正在相邻的终端上工作。
    Athena: 嗨,这个分时操作系统实在太慢了。我根本无法工作,因为每个人都登上去了。

    Euripides: 不要对我报怨。我只是在这工作。
    Athena: 你知道我们需要什么吗?我们需要给每一个人一台工作,这样大家就不会担心计算机的速度了。并且,我们需要一个网络把所有的计算机都联起来。
    Euripides: 好。那么我们差不多要一千台工作站?
    Athena: 差不多吧。
    Euripides: 你知道一台普通的工作站的硬盘有多大吗?那里放不下所有的软件。
    Athena: 我已经有主意了。我们可以把系统软件放到服务器上。当你登录到工作站的时候,工作站会通过网络与其中一台服务器上的系统软件联系。这样的设置让一组工作站都使用同一份系统软件,并且利于系统软件的升級。只需改动服务器就可以了。
    Euripides: 好的。个人的文件怎到办呢?在分时操作系统上,我可以登录并从终端上取走我的文件。我能到工作站上取我的文件吗?我要象PC用户一样把我的文件放到磁盘上去吗?我希望不。
    Athena: 我想我们可以其它机器来存文件。你可以到任何一台机器上登录去取你的文件。
    Euripides: 打印怎么办呢?每个工作站都要有自已的打印机吗?谁来付钱?电子邮件呢?你怎么把邮件送到所有的工作站上去呢?
    Athena: 啊.....很明显我们没钱为每个人配一台打印机,但我们有专门的机器做打印服务。你把请求送到服务器,它就为你打印。邮件也可以这样做。专门有一台邮件服务器。你如果想要你的邮件,就联系邮件服务器,取走你的邮件。
    Euripides: 你的工作站系统听起来很不错。如果我有一台,你知道我要做什么吗?我要找出你的用户名,让我的工作站认为我就是你。然后我就去邮件服务器取走你的邮件。我会联上你的文件服务器,移走你的文件,然后--
    Athena: 你能做得到吗?
    Euripides: 当然!这些网络服务器怎么会知道我不是你?
    Athena: 嗯,我不知道.我想我需要认真思考一下.
    Euripides: 好吧。你想出来后告诉我.
    第二幕
    Euripides的办公室,第二天早上。Euripides坐在他的桌子旁边,读着他的邮件。Athena来敲门.
    Athena: 我已经想出怎样保护一个开放的网络系统,使象你那样不道德的人不能用别人的名字使用网络服务。
    Euripides: 真的吗?坐吧。
    她坐下了。
    Athena: 在我开始描述之前,我可以为我们的讨论先做一个约定吗?
    Euripides: 什么约定?
    Athena: 好,假设我这样说:"我想要我的邮件,于是我与邮件服务器联系,请求它把邮件送到我的工作站上来。"实际上我并没有联系服务器。我用一个程序来与服务器联系并取得我的邮件,这个程序就是这个服务的客户端。 但我不想每次与服务器交互的时侯说:"客户端怎样怎样".我只想说:"我怎样怎样,"记住,客户端在代表我做所有的事。这样可以吗?
    Euripides: 当然。没问题.
    Athena: 好。那么我要开始阐述我所解决的问题了。在一个开放的网络环境中,提供服务的机器必须能够识别请求服务的实体的身份。如果我去邮件服务器申请我的邮件,服务程序必须能够验证我就是我所申明的那个人。
    Euripides: 没错.
    Athena: 你可以用一个笨办法解决这个问题:服务器让你输入你的口令。通过输口令的办法我可以证明我是谁。
    Euripides: 那确实很笨拙。在像那样的系统里面,每一个服务器必须知道你的口令。如果网络有一千个用户,那每个服务器就要知道一千个口令。如果你想改变口令,你就必须联系所有服务器,通知它们修改口令。我想你的系统不会那么笨。
    Athena: 我的系统没那么笨。它是象这样工作的:不光人有口令,服务也有口令。每个用户知道他们自已的口令,每个服务也知道它自已的口令。有一个认证服务知道所有的口令,用户的和服务的。认证服务把口令保存在一个单独的中央数据库中。
    Euripides: 这个认证服务有一个名字吗?
    Athena: 我还没想好。你想一个吧?
    Euripides: 把死人送过冥河的人是谁?
    Athena: Charon?
    Euripides: 对,就是他。如果他不能证实你的身份的话,他就不会把你送过河。
    Athena: 你瞎编,是不是想重写希腊神话。Charon不关心你的身份,他只是确定你死了
    没有。
    Euripides: 你有更好的名字吗?
    停了一下。
    Athena: 没有,真的没有。
    Euripides: 好,那我们就把这个认证服务“Charon”。
    Athena: 好,我猜我该描述一下这个系统了吧,嗯?
    比如说我们想要一种服务:邮件。在我的系统里面你无法使用一种服务,除非Charon告诉服务你确实是你所申明的人。也就是说你必须得到Charon的认证才能使用服务。当你向Charon请求认证的时候,你必须告诉Charon你要使用哪一个服务。如果你想用邮件,你要告诉Charon。 Charon请你证明你的身份。于是你送给它你的密码。Charon把你的密码和它数据库中的密码相比较。如果相等,Charon就认为你通过了验证。 Charon现在就要让邮件服务知道你通过了验证。既然Charon知道所有服务的密码,它也知道邮件服务的密码。Charon把邮件服务的密码给你,你就可以使用这个密码使邮件服务相信你已通过验证。 问题是,Charon不能直接给你密码,因为你会知道它。下次你想要邮件服务的时候,你就会绕过Charon使用邮件服务而不需要认证。你也可以假装某人来使用邮件服务。 所以不是直接给你邮件服务的密码,Charon给你一张邮件服务的“票”。这张票含有你的名字,并且名字是用邮件服务的密码加密的。 拿到票,你就可以向邮件服务请求你的邮件。你向邮件服务提出请求,并用你的票来证明你的身份。 服务用它自已的密码来把票解密,如果票能被正确的解密,服务器将票里的用户名取出。服务把这个名字和随票一起送上的用户名进行比较。如果相符,服务器就认为你通过了验证,就把你的邮件发给你。
    你认为怎么样?
    Euripides: 我有些问题。
    Athena: 我猜到了。请讲。
    Euripides: 当服务解密一张票的时候,它如何知道它是被正确的解密的?
    Athena: 我不知道。
    Euripides: 也许你应该在票里包含有服务的名字。这样当服务解密票的时候,它就可以通过能否在票中找到自已的名字来判断解密是否正确。
    Athena: 很好。那票就应该是这个样子:
    (她把下面的东西写在了一张纸上)
    票-{用户名:服务名}
    Euripides: 那票就只包含用户名和服务名?
    Athena: 用服务的口令加密。
    Euripides: 我不认为这些信息就可以让票安全。
    Athena: 什么意思?
    Euripides: 假设你向Charon请求一张邮件服务的票。Charon准备了一张有你名字“tina”
    的票。假设在当票从Charon传给你的过程中我拷了一份。假设我让我的工作站相信我的用户名是”tina“。邮件客户程序认为我就是你。用你的名字邮件客户程序用偷来的票向邮件服务器提出请求。邮件服务器把票解密,认为它是合法的。票里的用户名和发送该票的用户名是匹配的。邮件服务器就会发给 我你的邮件。
    Athena: 喔!那可不太好。
    Euripides: 但是我想到了一个办法来解决这个问题。或者说部分解决。我想Charon应该在票中包含更多的信息。除了用户名,票还应包含请求票的用户的IP地址。这将给你增加一层安全性。 我来演示。假设现在我偷了你的票。这票有你工作站的IP地址,并且这地址配不上我的
    工作站的地址。用你的名字我把偷来的票送给邮件服务器。服务程序把用户名和网络地址从票中解出,并试图匹配用户名和网络地址。用户名匹配可网络地址不匹配。服务器拒绝了这张票,因为它明显是偷来的。
    Athena: 英雄,英雄!我怎么会没想到。
    Euripides: 好了,这就是我要表述的。
    Athena: 那么票应该是这个样子的。
    她把下面的东西写在了黑板上。
    票-{用户名:地址:服务名}
    Athena: 现在我真的很激动。让我们来建一个Charon系统看看它是否工作!
    Euripides: 没那么快。对于你的系统我还有些问题。
    Athena: 好吧。(Athena从她的椅子上探出了身子)快说。
    Euripides: 听起来好像每次我想要得到服务我都要去取一张新票。如果我整天的工作,我可能不只一次的要取我的邮件。我每次取邮件都要去取一张新票吗?如果真是这样,我不喜欢你的系统。
    Athena: 啊。。。我不明白为什么票不能被重用。如果我已经得到了一张邮件服务的票,我可以一次又一次使用它。当邮件客户程序用你的名字请求了服务,它就传了一份票的拷贝给服务。
    Euripides: 好一些。但我仍有问题。你似乎暗示我每次使用还没有票的服务时,我都必须给Charon我的密码我登录后想取我的文件。我向Charon请求我的票,这意味着我不得不使用我的密码。然后我想读我的邮件。又向Charon发一次请求,我又要输一次我的密码。现在假设我想把我的邮件送去打印。我又要向Charon发一次请求。你知道了吧?
    Athena: 啊,是的,我明白了。
    Euripides: 并且如果这还不够糟的话,想想看:它好像是这样,当每次你要向Charon认证的时候,你就要用明文在网络上传输你的口令。像你这样的聪明人可以监视网络并且得到别人的口令。如果我得到你的口令,我就可以用你的名字来使用任何服务。
    Athena叹了口气。
    Athena: 确实有严重的问题。我想我该回设计室去了。
    第三幕
    第二天一早,Athena在咖啡间遇上了Euripides。在Euripides倒咖啡的时候,Athena拍了
    拍Euripides.
    Athena: 我有了一个新的Charon的版本来解决我们的问题。
    Euripides: 真的吗?好快呀。
    Athena: 好,你看,这些问题困扰了我一夜。
    Euripides: 一定是你良心发现了。我们去那边的小会议室吧?
    Athena: 好的。
    两人去了小会议室。
    Athena: 我要重新描述问题,但我要根据我们的需要进行适当的转换。
    Athena清了清嗓子。
    Athena: 第一个限制:用户只输一次口令,在他们工作站启动的时候,这意味着当你需要申请新的服务的票时,不需输入你的口令。第二个限制:口令不能在网络上进行明文传输。
    Euripides: 好的。
    Athena: 我以第一项限制开始:你只需要输入你的口令一次。我创造了一个新的网络服务来解决这个问题。 它叫做“票据授权”服务,这个服务把Charon的票给用户。使用它必须要有票:票据授权的票。 票据授权服务其实只是Charon的一个版本,它可以存取Charon的数据库。它是Charon的一部分,可以让你通过票而不是口令来进行认证。 总之,认证系统现在是象这样工作的:你登录到一个工作站,用一个叫kinit的程序与Charon 服务器通讯。你向Charon证明你的身份,kinit程序取得一张票据授权票。 现在你想从邮件服务器上取你的邮件。你还没有邮件服务器的票,所以你用“票据授权”票去取邮件服务的票。你不需要使用口令去取新的服务票。
    Euripides: 每次我想要另一种网络服务的时候,我都要去取一张“票据授权”票吗?
    Athena: 不。记住,上次我们已经同意票是能被重用的。一旦你要用到票据授权票,直接用就可以了。
    Euripides: 好,有道理。既然你能重用票,一旦你得到了某个服务的票,你就无需再去取了。
    Athena: 对啊,那不好吗?
    Euripides: 好的,我没话说,只要你在取得票据授权票的时候没有用明文在网上传输你的口令。
    Athena: 如我所说,我已解决了这个问题。听起来好像是,当我说我要和Charon联系取
    得票据授权票的时候,你就要在网络上传输明文密码。但其实不是这样的。 实际上是,当你用kinit程序取得票据授权票的时候,kinit没有把你的口令送
    给Charon服务器,kinit只送你的用户名。
    Euripides: 很好。
    Athena: Charon用用户名去查找你的口令。然后Charon就会组一个包含票据授权票的包。在送给你之前,Charon用你的口令去把这个包加密。 你的工作站收到了包。你输入你的口令。kinit用你的口令对这个包进行解密。如果成功你就向Charon成功的进行了认证。你现在有了票据授权票,你可以用这张票来取得其它的票。
    这些奇思妙想怎么样?
    Euripides: 我不知道...我正在思考。你知道你的系统一部分工作得很好。你的系统只需要我认证一次。以后,Charon会给我服务的票而我需要关心。天衣无缝,天衣无缝。但服务票的设计还是有一些困扰我。服务票是可重用的。我同意它们应该能被重用,但重用的服务票,由于它们自身的性质,是非常危险的。
    Athena: 什么意思?
    Euripides: 这样看。假设你正在用一个不安全的工作站。在你登入后,你需要邮件服务票,打印票,和文件服务票。假设你无意中在你退出后留下了那些票。 现在假设我登录到那个工作站并且发现了那些票。我想制造一些麻烦,于是我就用你的名字登录了。既然那些票上是你的名字,那我就可以取你的邮件,打大量的文件。这些完全是因为这些票被偶然的放在了那里。 并且我还可以把这些票拷走,永远的使用它们。
    Athena: 但是这很好解决。我们可以写一个程序,在用户退出的时候把票销毁掉,这些
    票也主不能再用了。
    Euripides: 那么很明显你的统应该有一个票据销毁程序,让用户依赖这样的机制是非常愚蠢的。你不能指望用户在他们退出的时候会销毁票据。并且甚至不能依赖销毁票据本身,看下面的情况。 我有一个程序可以监视网络并且拷内别人的服务票据。假设我想牺牲你。我等你登到工作站的时候,打开我的程序并拷贝一份你的票。 我等你退出并离开。我把我的工作站的地址调整为你登录时用的地址。我让工作站认为我是你。我有你的票,你的用户名,你的地址。我可以用这些票来使用你的服务。
    你离开工作站时销毁你的票已没并系。这些我偷来的票可以一直使用下去,因为你现在的票并没有可以使用多少次的期限,或可以使用多长的时间。
    Athena: 哦,我明白你所说的了!票不能是永远合法的,因为它可能是一个非常大的安全隐患。我们应该限制每一张票可以用多长的时间,也许可以给每张票设一个有效期。
    Euripides: 非常正确。我想票需要增加两项信息:生存期表示票多长时间内是合法的,和一个时间标记来说明Charon是什么时候发出这张票的。
     Euripides走到了黑板写下了如下的内容:
      票{用户名:地址:服务名:有效期:时间戳}
    Euripides: 现在当服务解开票时,它检查票的用户名,地址是否与发送者匹配,然后它
    用有效期和时间戳来检查票是否有效。
    Athena: 很好。典型的票使用哪长的有效期呢?
    Euripides: 我不知道。也许是一个典型工作站的工作周期。就八小时吧。
    Athena: 那如果我在工作站呆的时间超过八小时,所有的票将会失效。包括票据授权票。那我就要重新向Charon作认证,在八小时以后。
    Euripides: 是不是不合理?
    Athena: 我想不是。好我们就定下来吧--票在八小时后失效。现在我有一个问题问你。假设我从网络上拷了 你的票--。
    Euripides: (眨了眨眼睛)啊,Tina!你不会真的这样做吧?
    Athena: 这只是为了讨论。我拷了你的票。现在我等你退出并离开。假设你有一个医生的约会或聚会要参加,你在两个小时后退出,并且你在退出之前销毁了你的票。
    但我已经偷了你的票,它们还可以使用六小时。这给了我足够的时间用你的名义去取你的文件并打印一千份什么东西。 你看,时间戳工作的很好如果小偷选择在它失效以后来用的话。如果小偷能在它失效之前用...。
    啊,好...当然,你是对的。
    Athena: 我想我们遇上了一个大问题了。(她叹了口气)
    停了一下。
    Euripides: 我想这意味着你今晚要忙了。再来点咖啡?
    Athena: 为什么不。
    第四幕
    第二天早上在Euripides的办公室。Athena来敲门。
    Euripides: 你今早有黑眼圈了。
    Athena: 好了,你知道的。又是一个漫漫长夜。
    Euripides: 你解决了重演的问题了吗?
    Athena: 我想是的。
    Euripides: 请坐。
    她坐下了。
    Athena: 照旧,我重申一下问题。票是可重用的,在一个限定的时间内(八小时)。如果谁偷了你的票并在它失效之前使用,我们毫无办法。
    Euripides: 确实如此。
    Athena: 我们可以把这个问题理解为设计一种别人无法重用的票。
    Euripides: 但这样的话你每次用新服务时都要取一张新票。
    Athena: 对。但那是很笨的解决办法。(稍顿。)啊,我怎样继续我的讨论呢?(她沉思了一会儿)。
    好的,我要重述一个问题,看有什么必须条件。网络服务必须能够证明使用票的人就是票上所申明的人。 我来顺着认证的过程再走一遍,这样我就可以演示我的解决方案。 我现在想用一个网络服务。我通过启动工作站上的客户端来使用它。客户端送三样东西给服务器:我的名字,我的工作站的网络地址,适当的服务票据。 这张票包含了申请这张票的人的名字和他(她)申请时所使用的工作站的地址。它也包含了票的有效期和时间戳。所有这些信息都被服务的密码加密了。
    我们现在的认证模式基于以下的测试:
    服务能对票解密吗?
    票在有效期以内吗?
    票中的名字和地址与申请者的名字和地址匹配吗?
    这些测试证明了什么?
    第一个测试证明了票是不是来自Charon.如果票不能被适当的解密,说明票不是来自真正
    的Charon.
    真正的Charon会用服务的票来加密票。Charon和服务是唯一知道服务密码的两个实体。
    如果票被成功的解密,服务知道它来自于真的Charon.这个测试防止了有人伪造假票。
    第二项测试检查票是否在有效期以内。如果过期,服务拒绝。这项测试阻止使用旧票,
    因为票可能是偷来的。
    第三项测试检查票的用户名和地址是否匹配请求者的用户名和地址。如果测试失败,说
    明使用者使用了别人的票。这张票当然被拒绝。
    如果名字和地址匹配,这个测试证明了什么?什么也没有。票可以被偷走,用户名和网
    络地址都可以被改变,如果需要的话。正如我昨天指出的那样,票可以在有效期内被盗用。
    因为服务不能确定票的发送者是不是合法用户。
    服务之所以无法判断是因为它没有与用户共享一个秘密。这样看。假如我正在埃尔斯诺
    尔(哈姆雷特中的城堡)值勤,你打算来和我换班。但除非你说出正确的口令,否则我不
    会与你换班的。我们共享了一个秘密。它可能是某人为所有值勤的人所设的。
    于是昨晚我就在想,为什么Charon不能为合法用户与服务之间设一个口令呢?Charon发
    一份口令给服务,同时发一份给用户。当服务从用户那里收到一张票,它可以用这个口令
    检验用户的合法性。
    Euripides: 等一下。Charon如何同时发两份口令?
    Athena: 票据的拥用者从Charon的回应中得到口令,像这个样子:
    她在黑板上写下了:
    Charon的回应-[口令|票]
    服务从票中获取口令。票的格式如下:
    票-{口令:用户名:地址:服务名:有效期:时间戳}
    当你要请求服务时,客户端程序生成一个‘验证器’。验证器包含了你的名字和你工作站的地址。客户端用口令把这些信息加密,口令是你请求票据时得到的。
     验证器-{用户名:地址}用口令加密。
    生成验证器以后,客户端把它和票一起送给服务。因为服务没有口令,所以它不能解密
    验证器。口令在票中,于是服务先解开票。
    解开票以后,服务得到以下的东西:
    票的有效期和时间戳;
    票的拥有者的名字;
    票拥有者的网络地址。
    口令。
    服务检查票是否过期。如果一切正常,服务就用口令去解验证器。如果解密没有问题,服务将会得到一个用户名和网络地址。服务用它们去和票里的用户名和网络地址去匹配,如果正确,那么服务认为票的发送者确实是票的真实拥有者。
    Athena暂停了一下,清了清喉咙,喝了点咖啡。
    我认为口令验证器的机制解决了盗用的问题。
    Euripides: 也许。但我想。。。攻击这个系统我必须有验证器。
    Athena: 不。你必须同时拥有验证器和票。没有票,验证器是没有用的。解开验证器必须要有口令,服务必须解开票才会有口令。
    Euripides: 好,我明白了,你是说当客户程序联系服务时,它同时送上票和验证器?
    Athena: 是的,我就是这个意思。
    Euripides: 如是真是这样,什么可以阻止我把票和验证器都偷走呢?我可以写一个程序,如果我拥有了票和验证器,我就可以一直使用它至有效期结束。我只需改变我的用户名和工作站的地址。不是吗?
    Athena: (咬了咬她的嘴唇)是的。多沮丧啊。
    Euripides: 等等,等等,等等!这不难解决。票在有效期内是可重用的,但那并不意味着验证器是可重用的。假设我们设计了验证器只可以被用一次。这可以吗?
    Athena: 好,也许。我样来想一下,客户端程序生成验证器,然后把它和票一起送给服务。真的票和验证器比你拷贝的要先到。如果验证器只能被用一次,你的拷贝就失效了。 啊,这就对了。我样现在需要做的就是发明一和方法使得验证器只能被用一次。
    Euripides: 没问题。我们把有效期和时间戳放在上面。假设每个验证有两分钟的有效期。当你想用一个服务时客户端生成验证器,标上当前的时间,把它和票一起送给服务。 服务器收到了票和验证器,服务器解开验证器,它检查验证器的时间戳和有效期。如果验证器还没失效,所有其它的检查都通过了,那么服务器就认为你通过了认证。 假设我通过网络拷贝了一份验证器和票,我必须改变我的工作站的网络地址和我的用户名,这差不多要用几分钟。那是非常苛刻的要求,我不认为是可能的,除非。。。 嗯,有一个潜在的问题。假设不是在网络的转输中拷贝到票和验证器,我拷贝了一份原始的从Charon而来的包,这个包是你向Charon请求时的回应。 这个包,有两个口令在里面:一个是你的,一个是服务的。服务的口令隐藏在票中,我取不到,但另一个呢?那个你用来生成验证器的? 如果我得到了口令,我就用它来建自已的验证器,如果我能建自已的验证器,我就能攻破你的系统。
    Athena: 这就是我昨晚所想的,但是当我顺着票的处理过程一想,发现那样偷走验证器是不可能的。
    你在一台工作站坐下,用kinit程序得到你的票据授权票。kinit要求输入用户名,你输入以后,kinit把它送给Charon.Charon用你的名字查找你的口令,然后生成一张票据授权票。作为处理的一部分,Charon生成了一个你与票据授权服务共享的口令。Charon把口令和票据授权票一起送给你,并且在发关之前用你的口令将它加密。
    Charon送出了包。某人取得了这个包,但他们无能为力因为它是用你的口令加过密的。特别是,无人可以偷走票据授权服务的口令。 kinit收到了票据包并要求你输入你的口令。如果你输入正确的口令,kinit解开包取出了口令。 现在你注意kinit的处理,你去取你的邮件。你打开邮件客户端。这个程序查找一张邮件服务的票但没有找到(你还没取过你的邮件)。客户端用票据授权票去申请一张邮件服务的票。 客户端为票据授权的过程生成了一个验证器,并用票据授权的口令把验证器加密。客户端把验证器送给了Charon,票据授权票,你的名字,你的工作站的地址,邮件服务的名字。票据授权服务收到了这些东西,并通过了认证检查。如果一切都通过,票据授权服务将会得到那个与你共享的口令。现在票据授权服务为你生成了一张邮件服务的票,在这个过程中生成了一个你与邮件服务共享的口令。票据授权服务把这些东西打成包送给你的工作站。包里有票和口令。在送包之前,票据授权服务用票据授权的口令把包加密。做完以后,包被送出去。 这样邮件服务票的包通过网络被送了出来。假设网络上的某人将它复制了一份。他不幸的发现包是用票据认证的口令加过密的。既然无法解密,他就不能得到邮件口令。没有口令,他就不能使用任何在网络上传送的邮件服务的票。 现在我觉得我们是安全的。你认为呢?
    Euripides: 也许吧。
    Athena: 也许!你就只会说这个吗!
    Euripides: (大笑)别在意。你现在应该知道我处理问题的方式了。我猜我和你昨晚都工
    作到了半夜。
    Athena: 哼!
    Euripides: 好的,大半夜。实际上,这个系统似乎是完全可行的。口令的方案解决了我
    昨晚想到的一个问题:相互验证的问题。
    稍顿。
    我说一下好吗?
    Athena: (有点冷淡)请便。
    Euripides: 你真好。(Euripides清了清自已的嗓子)昨晚,当口令和验证器在我脑子里转的时候,我想去找出这个系统新的问题,我想我发现了一个很严重的问题。我下面就演示一下。
    假设你厌倦了现在的工作,决定换一个。你想用公司的激光打印机打印求职信,把它们送给猎头和其它的雇主。于是你输入打印命令,命令去取得服务票,然后把票送到打印机。这是你认为它应该被送到的地方。实际上你并不知道你的请求被送到了正确的打印服务器。 假设一些无耻的人--比如说你的老板--调整了系统,把你的请求送到了他办公室的打印机。他的打印服务不关心票的内容。它告诉你的工作站服务已准备好打印你的文件。打印命令被送到了假的打印服务器,你有麻烦了。 我从相反的方向表达了相同的问题。用口令和验证器,Charon能够保护的它的服务器防止错误的用户使用,但它不能保护它的用户使用错误的服务器。系统需要为客户端程序提供一种验证服务器的方法,在它向服务器发送敏感信息之前。系统必须允许交互验证。 但口令的方案解决了这个问题。让我们回到打印服务器的场景。我想要打印客户程序确
    认它送交的服务是合法的服务。 这就是程序要做的。我输入打印命令并给出一个文件名。这时我已经有了打印服务票和口令。客户程序用密码生成了一个验证器,然后把验证器和票送给了假设的打印服务器。客户端这时还没有送打印文件,它在等待从服务的返回。 真的服务收到票和验证器,把票解密并得到口令,然后用口令解开验证器。这样服务端做完了所有的认证。 测试已经确认了我的身份。现在服务程序要准备一个响应包来证实它自已的身份。它用口令加密了返回包,并把包送给了等待的客户端。 客户端收到了包并试图用口令把它解开。如果包被正确的解开得到了正确的服务器响应信息,客户端程序就知道了这个服务器是合法的服务器。然后这时客户端向它发出打印命令。 假设我的老板改变了一下系统使得他的打印机看起来好像是我想要用的那个。我的客户端送了票和验证器给它并等待它的响应。假冒的打印服务无法生成正确的响应因为它无法把票解开并得到口令。这样的话客户端就不会送打印命令给它因为客户端没有得到正确的
    响应。最后客户端放弃等待并退出。我的打印没有完成,但至少我的求职信不会放在我的
    对头的桌子上。
    好啊,我想我们有了Charon认证系统的坚实的基础。
    Athena: 也许。不管怎么说,我不喜欢Charon这个名字。
    Euripides: 你不喜欢吗?什么时候?
    Athena: 我从来都不喜欢,因为它的名字听起来没意义。有一天我和我荷迪斯(冥王)叔

    谈到了这个,他推荐了另一个名字:冥王的三个头的看门狗。
    Euripides: 啊,你是说“Cerberus".
    Athena: 你说什么语言啊!"Cerberus"实际上是。。。
    Euripides: 哦,不叫这个吗?
    Athena: 当然,谁让你是罗马人!而我是希腊人,它是一条希腊的看门狗,它的名字是

    Kerberos“,”Kerberos“是‘K’打头的。
    Euripides: 好吧,好吧,别发火。我同意这个名字。实际上,它有一个好的脖环。再见
    吧,Charon,欢迎你,Kerberos.
    后记
    这篇对话是于1988年写的,是为了帮助读者理解Kerberos V4的运行方式。经过了这么多年,它仍然非常好的服务于此。当我把这篇文章转换成HTML的时候,我惊讶的发现这个文档对Kerberos V5仍然非常有用。虽然很多东西改变了,但核心概念并没有变。实际上,Kerberos V5对Kerberos只做了两处改变。
    第一处改变是因为意识到验证器用少于五分钟的有效期不足以防止攻击者进行重演,如果攻击者是用一个程序自动的截取票和验证器并进行重演的话。 在Kerberos V5中,验证器真正的只能用一次因为服务器用‘重演缓冲区’保存了最近一次提交的验证器的信息。如果攻击者试图截取验证器并重用它,‘重演缓冲区’会发现验证器已经被提交了。
    第二个主要改变是Kerberos送给kinit服务票的时候,票不再是用用户的口令加密。它已经用票据授权服务的口令加过密了。票据授权服务的票被用来获取其它票的时候,它直接就被传输了。因此票不需要再用用户的口令加密一次。(服务器响应的其它部分,如口令,仍然是用用户的口令加密的。) 一个类似的改变也应用到票据授权服务协议;从票据授权服务返回的票也不再用票据授
    权服务的口令来加密了,因为它所包含的票已经被对应的服务的口令加过密了。举例来说

    Kerberos V4的包像这样:
    KDC_REPLY = {TICKET, client, server, K_session}K_user
    意思是:{}中的内容是用K_user来加密的。
    TICKET = {client, server, start_time, lifetime, K_session}K_server
    在Kerberos V5中,KDC_REPLY现在看起来像这样:
    KDC_REPLY = TICKET, {client, server, K_session}K_user
    (注意:票已经不再用K_user来加密了)
    当然,Kerberos V5中还有许多新特性。用户可以在另一个网络中安全的提交他们的票;并且,用户可以把他们的一部分认证权转给服务器,这样服务器就可以作为用户的代理。其它的新特性包括:用更好的加密算法替换了DES加密算法,如三重DES加密。读者如果对V
    4 与V5的变化感兴趣的话,可以读一下"The Evolution of the Kerberos Authentication System",作者是Cliff Neumann和Theodore Tso. 我希望你能对这篇介绍Kerberos协议的文章感兴趣。我祝愿你在未来的探索中更进一步

  • http://www.cnblogs.com/artech/archive/2007/07/10/811970.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 InfoSession 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的认证。

    基本原理
    引入Key Distribution: KServer-Client从何而来
    引入Authenticator : 为有效的证明自己提供证据
    引入Ticket Granting  Service:如何获得Ticket
    Kerberos的3个Sub-protocol:整个Authentication的流程
    User2User Protocol: 有效地保障Server的安全
    Kerberos的优点的优点

    四、引入Ticket Granting  Service

    通过上面的介绍,我们发现Kerberos实际上一个基于Ticket的认证方式。Client想要获取Server端的资源,先得通过Server的认证;而认证的先决条件是Client向Server提供从KDC获得的一个有Server的Master Key进行加密的Session Ticket(Session Key + Client Info)。可以这么说,Session Ticket是Client进入Server领域的一张门票。而这张门票必须从一个合法的Ticket颁发机构获得,这个颁发机构就是Client和Server双方信任的KDC, 同时这张Ticket具有超强的防伪标识:它是被Server的Master Key加密的。对Client来说, 获得Session Ticket是整个认证过程中最为关键的部分。

    上面我们只是简单地从大体上说明了KDC向Client分发Ticket的过程,而真正在Kerberos中的Ticket Distribution要复杂一些。为了更好的说明整个Ticket Distribution的过程,我在这里做一个类比。现在的股事很火爆,上海基本上是全民炒股,我就举一个认股权证的例子。有的上市公司在股票配股、增发、基金扩募、股份减持等情况会向公众发行认股权证,认股权证的持有人可以凭借这个权证认购一定数量的该公司股票,认股权证是一种具有看涨期权的金融衍生产品。

    而我们今天所讲的Client获得Ticket的过程也和通过认股权证购买股票的过程类似。如果我们把Client提供给Server进行认证的Ticket比作股票的话,那么Client在从KDC那边获得Ticket之前,需要先获得这个Ticket的认购权证,这个认购权证在Kerberos中被称为TGT:Ticket Granting Ticket,TGT的分发方仍然是KDC。

    我们现在来看看Client是如何从KDC处获得TGT的:首先Client向KDC发起对TGT的申请,申请的内容大致可以这样表示:“我需要一张TGT用以申请获取用以访问所有Server的Ticket”。KDC在收到该申请请求后,生成一个用于该Client和KDC进行安全通信的Session Key(SKDC-Client)。为了保证该Session Key仅供该Client和自己使用,KDC使用Client的Master Key自己的Master Key对生成的Session Key进行加密,从而获得两个加密的SKDC-Client的Copy。对于后者,随SKDC-Client一起被加密的还包含以后用于鉴定Client身份的关于Client的一些信息。最后KDC将这两份Copy一并发送给Client。这里有一点需要注意的是:为了免去KDC对于基于不同Client的Session Key进行维护的麻烦,就像Server不会保存Session Key(SServer-Client)一样,KDC也不会去保存这个Session Key(SKDC-Client),而选择完全靠Client自己提供的方式。

     


    当Client收到KDC的两个加密数据包之后,先使用自己的Master Key对第一个Copy进行解密,从而获得KDC和Client的Session Key(SKDC-Client),并把该Session 和TGT进行缓存。有了Session Key和TGT,Client自己的Master Key将不再需要,因为此后Client可以使用SKDC-Client向KDC申请用以访问每个Server的Ticket,相对于Client的Master Key这个Long-term Key,SKDC-Client是一个Short-term Key,安全保证得到更好的保障,这也是Kerberos多了这一步的关键所在。同时需要注意的是SKDC-Client是一个Session Key,他具有自己的生命周期,同时TGT和Session相互关联,当Session Key过期,TGT也就宣告失效,此后Client不得不重新向KDC申请新的TGT,KDC将会生成一个不同Session Key和与之关联的TGT。同时,由于Client Log off也导致SKDC-Client的失效,所以SKDC-Client又被称为Logon Session Key

    接下来,我们看看Client如何使用TGT来从KDC获得基于某个Server的Ticket。在这里我要强调一下,Ticket是基于某个具体的Server的,而TGT则是和具体的Server无关的,Client可以使用一个TGT从KDC获得基于不同Server的Ticket。我们言归正传,Client在获得自己和KDC的Session Key(SKDC-Client)之后,生成自己的Authenticator以及所要访问的Server名称的并使用SKDC-Client进行加密。随后连同TGT一并发送给KDC。KDC使用自己的Master Key对TGT进行解密,提取Client Info和Session Key(SKDC-Client),然后使用这个SKDC-Client解密Authenticator获得Client Info,对两个Client Info进行比较进而验证对方的真实身份。验证成功,生成一份基于Client所要访问的Server的Ticket给Client,这个过程就是我们第二节中介绍的一样了。 


    五、Kerberos的3个Sub-protocol:整个Authentication

    通过以上的介绍,我们基本上了解了整个Kerberos authentication的整个流程:整个流程大体上包含以下3个子过程:

    1. Client向KDC申请TGT(Ticket Granting Ticket)。
    2. Client通过获得TGT向DKC申请用于访问Server的Ticket。
    3. Client最终向为了Server对自己的认证向其提交Ticket。

    不过上面的介绍离真正的Kerberos Authentication还是有一点出入。Kerberos整个认证过程通过3个sub-protocol来完成。这个3个Sub-Protocol分别完成上面列出的3个子过程。这3个sub-protocol分别为:

    1. Authentication Service Exchange
    2. Ticket Granting Service Exchange
    3. Client/Server Exchange

    下图简单展示了完成这个3个Sub-protocol所进行Message Exchange。

     


    1. Authentication Service Exchange

    通过这个Sub-protocol,KDC(确切地说是KDC中的Authentication Service)实现对Client身份的确认,并颁发给该Client一个TGT。具体过程如下:

    Client向KDC的Authentication Service发送Authentication Service Request(KRB_AS_REQ), 为了确保KRB_AS_REQ仅限于自己和KDC知道,Client使用自己的Master Key对KRB_AS_REQ的主体部分进行加密(KDC可以通过Domain 的Account Database获得该Client的Master Key)。KRB_AS_REQ的大体包含以下的内容:

    • Pre-authentication data:包含用以证明自己身份的信息。说白了,就是证明自己知道自己声称的那个account的Password。一般地,它的内容是一个被Client的Master key加密过的Timestamp。
    • Client name & realm: 简单地说就是Domain name\Client
    • Server Name:注意这里的Server Name并不是Client真正要访问的Server的名称,而我们也说了TGT是和Server无关的(Client只能使用Ticket,而不是TGT去访问Server)。这里的Server Name实际上是KDC的Ticket Granting Service的Server Name

    AS(Authentication Service)通过它接收到的KRB_AS_REQ验证发送方的是否是在Client name & realm中声称的那个人,也就是说要验证发送放是否知道Client的Password。所以AS只需从Account Database中提取Client对应的Master Key对Pre-authentication data进行解密,如果是一个合法的Timestamp,则可以证明发送放提供的是正确无误的密码。验证通过之后,AS将一份Authentication Service Response(KRB_AS_REP)发送给Client。KRB_AS_REQ主要包含两个部分:本Client的Master Key加密过的Session Key(SKDC-Client:Logon Session Key)和被自己(KDC)加密的TGT。而TGT大体又包含以下的内容:

    • Session Key: SKDC-Client:Logon Session Key
    • Client name & realm: 简单地说就是Domain name\Client
    • End time: TGT到期的时间。

    Client通过自己的Master Key对第一部分解密获得Session Key(SKDC-Client:Logon Session Key)之后,携带着TGT便可以进入下一步:TGS(Ticket Granting Service)Exchange。

    2. TGS(Ticket Granting Service)Exchange

    TGS(Ticket Granting Service)Exchange通过Client向KDC中的TGS(Ticket Granting Service)发送Ticket Granting Service Request(KRB_TGS_REQ)开始。KRB_TGS_REQ大体包含以下的内容:

    • TGT:Client通过AS Exchange获得的Ticket Granting Ticket,TGT被KDC的Master Key进行加密。
    • Authenticator:用以证明当初TGT的拥有者是否就是自己,所以它必须以TGT的办法方和自己的Session Key(SKDC-Client:Logon Session Key)来进行加密。
    • Client name & realm: 简单地说就是Domain name\Client。
    • Server name & realm: 简单地说就是Domain name\Server,这回是Client试图访问的那个Server。

    TGS收到KRB_TGS_REQ在发给Client真正的Ticket之前,先得整个Client提供的那个TGT是否是AS颁发给它的。于是它不得不通过Client提供的Authenticator来证明。但是Authentication是通过Logon Session Key(SKDC-Client)进行加密的,而自己并没有保存这个Session Key。所以TGS先得通过自己的Master Key对Client提供的TGT进行解密,从而获得这个Logon Session Key(SKDC-Client),再通过这个Logon Session Key(SKDC-Client)解密Authenticator进行验证。验证通过向对方发送Ticket Granting Service Response(KRB_TGS_REP)。这个KRB_TGS_REP有两部分组成:使用Logon Session Key(SKDC-Client)加密过用于Client和Server的Session Key(SServer-Client)和使用Server的Master Key进行加密的Ticket。该Ticket大体包含以下一些内容:

    • Session Key:SServer-Client。
    • Client name & realm: 简单地说就是Domain name\Client。
    • End time: Ticket的到期时间。

    Client收到KRB_TGS_REP,使用Logon Session Key(SKDC-Client)解密第一部分后获得Session Key(SServer-Client)。有了Session Key和Ticket,Client就可以之间和Server进行交互,而无须在通过KDC作中间人了。所以我们说Kerberos是一种高效的认证方式,它可以直接通过Client和Server双方来完成,不像Windows NT 4下的NTLM认证方式,每次认证都要通过一个双方信任的第3方来完成。

    我们现在来看看 Client如果使用Ticket和Server怎样进行交互的,这个阶段通过我们的第3个Sub-protocol来完成:CS(Client/Server )Exchange

    3. CS(Client/Server )Exchange

    这个已经在本文的第二节中已经介绍过,对于重复发内容就不再累赘了。Client通过TGS Exchange获得Client和Server的Session Key(SServer-Client),随后创建用于证明自己就是Ticket的真正所有者的Authenticator,并使用Session Key(SServer-Client)进行加密。最后将这个被加密过的Authenticator和Ticket作为Application Service Request(KRB_AP_REQ)发送给Server。除了上述两项内容之外,KRB_AP_REQ还包含一个Flag用于表示Client是否需要进行双向验证(Mutual Authentication)。

    Server接收到KRB_AP_REQ之后,通过自己的Master Key解密Ticket,从而获得Session Key(SServer-Client)。通过Session Key(SServer-Client)解密Authenticator,进而验证对方的身份。验证成功,让Client访问需要访问的资源,否则直接拒绝对方的请求。

    对于需要进行双向验证,Server从Authenticator提取Timestamp,使用Session Key(SServer-Client)进行加密,并将其发送给Client用于Client验证Server的身份。

    到此为止,Kerberos的整个过程大体上已经介绍完毕。不知道他们有没有意识到这其中有什么安全隐患?我在一开始在介绍Long-term Key和Short-term Key的时候就已经强调过:被Long-term Key加密的信息最好不要在网络中传递,然后Client从KDC获得的Ticket确是通过Server的Master Key加密的,这显然对Server来说是不安全的,为了解决这个问题,Kerberos引入了第4个Sub-protocol: User2User。

    基本原理
    引入Key Distribution: KServer-Client从何而来
    引入Authenticator : 为有效的证明自己提供证据
    引入Ticket Granting  Service:如何获得Ticket
    Kerberos的3个Sub-protocol:整个Authentication的流程
    User2User Protocol: 有效地保障Server的安全
    Kerberos的优点的优点
     

    六、User2User Sub-Protocol:有效地保障Server的安全

    通过3个Sub-protocol的介绍,我们可以全面地掌握整个Kerberos的认证过程。实际上,在Windows 2000时代,基于Kerberos的Windows Authentication就是按照这样的工作流程来进行的。但是我在上面一节结束的时候也说了,基于3个Sub-protocol的Kerberos作为一种Network Authentication是具有它自己的局限和安全隐患的。我在整篇文章一直在强调这样的一个原则:以某个Entity的Long-term Key加密的数据不应该在网络中传递。原因很简单,所有的加密算法都不能保证100%的安全,对加密的数据进行解密只是一个时间的过程,最大限度地提供安全保障的做法就是:使用一个Short-term key(Session Key)代替Long-term Key对数据进行加密,使得恶意用户对其解密获得加密的Key时,该Key早已失效。但是对于3个Sub-Protocol的C/S Exchange,Client携带的Ticket却是被Server Master Key进行加密的,这显现不符合我们提出的原则,降低Server的安全系数。

    所以我们必须寻求一种解决方案来解决上面的问题。这个解决方案很明显:就是采用一个Short-term的Session Key,而不是Server Master Key对Ticket进行加密。这就是我们今天要介绍的Kerberos的第4个Sub-protocol:User2User Protocol。我们知道,既然是Session Key,仅必然涉及到两方,而在Kerberos整个认证过程涉及到3方:Client、Server和KDC,所以用于加密Ticket的只可能是Server和KDC之间的Session Key(SKDC-Server)。

    我们知道Client通过在AS Exchange阶段获得的TGT从KDC那么获得访问Server的Ticket。原来的Ticket是通过Server的Master Key进行加密的,而这个Master Key可以通过Account Database获得。但是现在KDC需要使用Server和KDC之间的SKDC-Server进行加密,而KDC是不会维护这个Session Key,所以这个Session Key只能靠申请Ticket的Client提供。所以在AS Exchange和TGS Exchange之间,Client还得对Server进行请求已获得Server和KDC之间的Session Key(SKDC-Server)。而对于Server来说,它可以像Client一样通过AS Exchange获得他和KDC之间的Session Key(SKDC-Server)和一个封装了这个Session Key并被KDC的Master Key进行加密的TGT,一旦获得这个TGT,Server会缓存它,以待Client对它的请求。我们现在来详细地讨论这一过程。

     


    上图基本上翻译了基于User2User的认证过程,这个过程由4个步骤组成。我们发现较之我在上面一节介绍的基于传统3个Sub-protocol的认证过程,这次对了第2部。我们从头到尾简单地过一遍:

    1. AS Exchange:Client通过此过程获得了属于自己的TGT,有了此TGT,Client可凭此向KDC申请用于访问某个Server的Ticket。
    2. 这一步的主要任务是获得封装了Server和KDC的Session Key(SKDC-Server)的属于Server的TGT。如果该TGT存在于Server的缓存中,则Server会直接将其返回给Client。否则通过AS Exchange从KDC获取。
    3. TGS Exchange:Client通过向KDC提供自己的TGT,Server的TGT以及Authenticator向KDC申请用于访问Server的Ticket。KDC使用先用自己的Master Key解密Client的TGT获得SKDC-Client,通过SKDC-Client解密Authenticator验证发送者是否是TGT的真正拥有者,验证通过再用自己的Master Key解密Server的TGT获得KDC和Server 的Session Key(SKDC-Server),并用该Session Key加密Ticket返回给Client。
    4. C/S Exchange:Client携带者通过KDC和Server 的Session Key(SKDC-Server)进行加密的Ticket和通过Client和Server的Session Key(SServer-Client)的Authenticator访问Server,Server通过SKDC-Server解密Ticket获得SServer-Client,通过SServer-Client解密Authenticator实现对Client的验证。

    这就是整个过程。

    七、Kerberos的优点

    分析整个Kerberos的认证过程之后,我们来总结一下Kerberos都有哪些优点:

    1.较高的Performance

    虽然我们一再地说Kerberos是一个涉及到3方的认证过程:Client、Server、KDC。但是一旦Client获得用过访问某个Server的Ticket,该Server就能根据这个Ticket实现对Client的验证,而无须KDC的再次参与。和传统的基于Windows NT 4.0的每个完全依赖Trusted Third Party的NTLM比较,具有较大的性能提升。

    2.实现了双向验证(Mutual Authentication)

    传统的NTLM认证基于这样一个前提:Client访问的远程的Service是可信的、无需对于进行验证,所以NTLM不曾提供双向验证的功能。这显然有点理想主义,为此Kerberos弥补了这个不足:Client在访问Server的资源之前,可以要求对Server的身份执行认证。

    3.对Delegation的支持

    Impersonation和Delegation是一个分布式环境中两个重要的功能。Impersonation允许Server在本地使用Logon 的Account执行某些操作,Delegation需用Server将logon的Account带入到另过一个Context执行相应的操作。NTLM仅对Impersonation提供支持,而Kerberos通过一种双向的、可传递的(Mutual 、Transitive)信任模式实现了对Delegation的支持。

    4.互操作性(Interoperability)

    Kerberos最初由MIT首创,现在已经成为一行被广泛接受的标准。所以对于不同的平台可以进行广泛的互操作。

    以下补充摘自wiki:

    Kerberos operation

    What follows is a simplified description of the protocol. The following shortcuts will be used:

    • AS = Authentication Server
    • TGS = Ticket Granting Server
    • SS = Service Server.

    In one sentence: the client authenticates itself to AS, then demonstrates to the TGS that it's authorized to receive a ticket for a service (and receives it), then demonstrates to the SS that it has been approved to receive the service.

    In more detail:

    1. A user enters a username and password on the client.
    2. The client performs a one-way hash on the entered password, and this becomes the secret key of the client.
    3. The client sends a clear-text message to the AS requesting services on behalf of the user. Sample Message: "User XYZ would like to request services". Note: Neither the secret key nor the password is sent to the AS.
    4. The AS checks to see if the client is in its database. If it is, the AS sends back the following two messages to the client:
      • Message A: Client/TGS session key encrypted using the secret key of the user.
      • Message B: Ticket-Granting Ticket (which includes the client ID, client network address, ticket validity period, and the client/TGS session key) encrypted using the secret key of the TGS.
    5. Once the client receives messages A and B, it decrypts message A to obtain the client/TGS session key. This session key is used for further communications with TGS. (Note: The client cannot decrypt the Message B, as it is encrypted using TGS's secret key.) At this point, the client has enough information to authenticate itself to the TGS.
    6. When requesting services, the client sends the following two messages to the TGS:
      • Message C: Composed of the Ticket-Granting Ticket from message B and the ID of the requested service.
      • Message D: Authenticator (which is composed of the client ID and the timestamp), encrypted using the client/TGS session key.
    7. Upon receiving messages C and D, the TGS decrypts message D (Authenticator) using the client/TGS session key and sends the following two messages to the client:
      • Message E: Client-to-server ticket (which includes the client ID, client network address, validity period and Client/server session key) encrypted using the service's secret key.
      • Message F: Client/server session key encrypted with the client/TGS session key.
    8. Upon receiving messages E and F from TGS, the client has enough information to authenticate itself to the SS. The client connects to the SS and sends the following two messages:
      • Message E from the previous step (the client-to-server ticket, encrypted using service's secret key).
      • Message G: a new Authenticator, which includes the client ID, timestamp and is encrypted using client/server session key.
    9. The SS decrypts the ticket using its own secret key and sends the following message to the client to confirm its true identity and willingness to serve the client:
      • Message H: the timestamp found in client's recent Authenticator plus 1, encrypted using the client/server session key.
    10. The client decrypts the confirmation using the client/server session key and checks whether the timestamp is correctly updated. If so, then the client can trust the server and can start issuing service requests to the server.
    11. The server provides the requested services to the client.

    Kerberos drawbacks

    • Single point of failure: It requires continuous availability of a central server. When the Kerberos server is down, no one can log in. This can be mitigated by using multiple Kerberos servers.
    • Kerberos requires the clocks of the involved hosts to be synchronized. The tickets have time availability period and, if the host clock is not synchronized with the clock of Kerberos server, the authentication will fail. The default configuration requires that clock times are no more than 10 minutes apart. In practice, NTP daemons are usually employed to keep the host clocks synchronized.
    • Password changing is not standardized, and differs between server implementations.
  • 私钥加密(对称加密 symmetric cryptography:私钥加密算法使用单个私钥来加密和解密数据。由于具有密钥的任意一方都可以使用该密钥解密数据,因此必须保护密钥不被未经授权的代理得到。私钥加密又称为对称加密,因为同一密钥既用于加密又用于解密。私钥加密算法非常快(与公钥算法相比),特别适用于对较大的数据流执行加密转换。Well-known secret key cryptographic algorithms include the Data Encryption Standard (DES), triple-strength DES (3DES), Rivest Cipher 2 (RC2), and Rivest Cipher 4 (RC4).

    通常,私钥算法(称为块密码)用于一次加密一个数据块。块密码(如 RC2、DES、TripleDES 和 Rijndael)通过加密将 n 字节的输入块转换为加密字节的输出块。如果要加密或解密字节序列,必须逐块进行。由于 n 很小(对于 RC2、DES 和 TripleDES,n = 8 字节;n = 16 [默认值];n = 24;对于 Rijndael,n = 32),因此必须对大于 n 的数据值一次加密一个块。 

    基类库中提供的块密码类使用称作密码块链 (CBC) 的链模式,它使用一个密钥和一个初始化向量 (IV) 对数据执行加密转换。对于给定的私钥k,一个不使用初始化向量的简单块密码将把相同的明文输入块加密为同样的密文输出块。如果在明文流中有重复的块,那么在密文流中将存在重复的块。如果未经授权的用户知道有关明文块的结构的任何信息,就可以使用这些信息解密已知的密文块并有可能发现您的密钥。若要克服这个问题,可将上一个块中的信息混合到加密下一个块的过程中。这样,两个相同的明文块的输出就会不同。由于该技术使用上一个块加密下一个块,因此使用了一个 IV 来加密数据的第一个块。使用该系统,未经授权的用户有可能知道的公共消息标头将无法用于对密钥进行反向工程。

    可以危及用此类型密码加密的数据的一个方法是,对每个可能的密钥执行穷举搜索。根据用于执行加密的密钥大小,即使使用最快的计算机执行这种搜索,也极其耗时,因此难以实施。使用较大的密钥大小将使解密更加困难。虽然从理论上说加密不会使对手无法检索加密的数据,但这确实极大增加了这样做的成本。如果执行彻底搜索来检索只在几天内有意义的数据需要花费三个月的时间,那么穷举搜索的方法是不实用的。

    私钥加密的缺点是它假定双方已就密钥和 IV 达成协议,并且互相传达了密钥和 IV 的值。并且,密钥必须对未经授权的用户保密。由于存在这些问题,私钥加密通常与公钥加密一起使用,来秘密地传达密钥和 IV 的值。

    最早、最著名的保密密钥或对称密钥加密算法DES(Data Encryption Standard)/DESede是由IBM公司在70年代发展起来的,并经政府的加密标准筛选后,于1976年11月被美国政府采用,DES随后被美国国家标准局和美国国家标准协会(American National Standard Institute,ANSI)承认。DES使用56位密钥对64位的数据块进行加密,并对64位的数据块进行16轮编码。与每轮编码时,一个48位的"每轮"密钥值由56位的完整密钥得出来。

    .NET 提供以下实现类以提供对称的密钥加密算法: 

     DESCryptoServiceProvider 

     RC2CryptoServiceProvider

     RijndaelManaged

     TripleDESCryptoServiceProvider

     

    公钥加密(不对称加密,RSA, DSA, DH asymmetric cryptography):公钥加密使用一个必须对未经授权的用户保密的私钥和一个可以对任何人公开的公钥。公钥和私钥都在数学上相关联;用公钥加密的数据只能用私钥解密,而用私钥签名的数据只能用公钥验证。公钥可以提供给任何人;公钥用于对要发送到私钥持有者的数据进行加密。两个密钥对于通信会话都是唯一的。公钥加密算法也称为不对称算法,原因是需要用一个密钥加密数据而需要用另一个密钥来解密数据。对称算法的根本原理就是单向函数,f(a)=b,但是用b很难得到a。

    公钥加密算法使用固定的缓冲区大小,而私钥加密算法使用长度可变的缓冲区。公钥算法无法像私钥算法那样将数据链接起来成为流,原因是它只可以加密少量数据。因此,不对称操作不使用与对称操作相同的流模型。

    双方(小红和小明)可以按照下列方式使用公钥加密。首先,小红生成一个公钥/私钥对。如果小明想要给小红发送一条加密的消息,他将向她索要她的公钥。小红通过不安全的网络将她的公钥发送给小明,小明接着使用该密钥加密消息。(如果小明在不安全的信道如公共网络上收到小红的密钥,则小明必须同小红验证他具有她的公钥的正确副本。)小明将加密的消息发送给小红,而小红使用她的私钥解密该消息。

    但是,在传输小红的公钥期间,未经授权的代理可能截获该密钥。而且,同一代理可能截获来自小明的加密消息。但是,该代理无法用公钥解密该消息。该消息只能用小红的私钥解密,而该私钥没有被传输。小红不使用她的私钥加密给小明的答复消息,原因是任何具有公钥的人都可以解密该消息。如果小红想要将消息发送回小明,她将向小明索要他的公钥并使用该公钥加密她的消息。然后,小明使用与他相关联的私钥来解密该消息。

    在一个实际方案中,小红和小明使用公钥(不对称)加密来传输私(对称)钥,而对他们的会话的其余部分使用私钥加密(由于对称加密快捷,用于实际的数据加密,而利用不对称加密的方式解决对称加密中私钥传递的不安全性,此为对称和不对称加密结合的加密方式)。

    公钥加密具有更大的密钥空间(或密钥的可能值范围),因此不大容易受到对每个可能密钥都进行尝试的穷举攻击。由于不必保护公钥,因此它易于分发。公钥算法可用于创建数字签名以验证数据发送方的身份。但是,公钥算法非常慢(与私钥算法相比),不适合用来加密大量数据。公钥算法仅对传输很少量的数据有用。公钥加密通常用于加密一个私钥算法将要使用的密钥和 IV。传输密钥和 IV 后,会话的其余部分将使用私钥加密。

    RSA系统是诸多此类算法中最著名、最多使用的一种。RSA公开密钥密码系统是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是来自于这三位发明者的姓的第一个字母RSA(Rivest-Shamir-Adleman)算法是基于大数不可能被质因数分解假设的公钥体系。简单地说就是找两个很大的质数。一个对外公开的为“公钥”(Prblic key) ,另一个不告诉任何人,称为"私钥”(Private key)。这两个密钥是互补的,也就是说用公钥加密的密文可以用私钥解密,反过来也一样。

    公钥的传输:要启动安全通讯,通信两端必须首先得到相同的共享密钥(主密钥),但共享密钥不能通过网络相互发送,因为这种做法极易泄密。Diffie-Hellman算法是用于密钥交换的最早最安全的算法之一。

    RSA算法:RSA算法是基于大数难于分解的原理。不但可以用于认证,也可以用于密钥传输,例子可以参考RSAUtil.java文件。那么用户A和B如何利用RSA算法来传输密钥呢?

    1:A产生一个密钥K,用B的公钥加密K,然后将得到的密文发送给B。

    2:B用自己的私钥解密收到的密钥,就可以得到密钥。

    DH算法:DH算法的出现就是用来进行密钥传输的。DH算法是基于离散对数实现的。DH算法的基本工作原理是:通信双方公开或半公开交换一些准备用来生成密钥的"材料数据",在彼此交换过密钥生成"材料"后,两端可以各自生成出完全一样的共享密钥。在任何时候,双方都绝不交换真正的密钥。通信双方交换的密钥生成"材料",长度不等,"材料"长度越长,所生成的密钥强度也就越高,密钥破译就越困难。除进行密钥交换外,IPSec还使用DH算法生成所有其他加密密钥。

    在通信前,用户A和B双方约定2个大整数n和g,其中1<g<n,这两个整数可以公开

    1) A随机产生一个大整数a,然后计算Ka=ga mod n(a需要保密)

    2) B随机产生一个大整数b,然后计算Kb=gb mod n(b需要保密)

    3) A把Ka发送给B,B把Kb发送给A

    4) A计算K=Kba mod n

    5) B计算K=Kab mod n

    由于Kba mod n= (gb mod n)a mod n= (ga mod n)b mod n,因此可以保证双方得到的K是相同的,K即是共享的密钥。可以参考JCE文档中的DH 3 party的例子。

    实际的一个用DH算法传递DES私钥的JAVA例子参看“JAVA上加密算法的实现用例”一文中的末一个例子,过程如下:假设A和B通信(JCE中只支持DH算法作为传递私钥的算法)

    A利用KeyPairGenerator类生成一个钥对类KeyPair并可通过generatePublic方法产生公钥PublicKey(puA)和getPrivate方法私钥PrivateKey(prA)。A把puA发给B。B用类X509EncodedKeySpec解码,然后利用KeyFactory类生成puA,转换成DHPublicKey类利用其getParams方法取得参数类DHParameterSpec,B再利用此参数类,通过KeyPairGenerator类的initialize方法生成KeyPairGenerator实例从而用generateKeyPair方法生成B的KeyPair。进而B生成puB和prB,B把puB发给A。A利用puB和prA作为参数,分别调用KeyAgreement类的init和doPhase方法初始化,然后用generateSecret方法生成各自的DES的密钥SecretKey,此密钥是相同的,即可用Cipher类进行加解密了。
     

    .NET 通过抽象基类 (System.Security.Crytography.AsymmetricAlgorithm) 提供下列非对称(公钥/私钥)加密算法:

     DSACryptoServiceProvider

     RSACryptoServiceProvider

    数字签名
    公钥算法还可用于构成数字签名。数字签名验证发送方的身份(如果您信任发送方的公钥)并帮助保护数据的完整性。

    为了使用公钥加密对消息进行数字签名,小红首先将哈希算法应用于该消息以创建消息摘要。该消息摘要是数据的紧凑且唯一的表示形式。然后,小红用她的私钥加密该消息摘要以创建她的个人签名。在收到消息和签名时,小明使用小红的公钥解密签名以恢复消息摘要,并使用与小红所使用的相同的哈希算法来散列消息。如果小明计算的消息摘要与从小红那里收到的消息摘要完全一致,小明就可以确定该消息来自私钥的持有人,并且数据未被修改过。如果小明相信小红是私钥的持有人,则他知道该消息来自小红。

    请注意,由于发送方的公钥为大家所周知,并且它通常包含在数字签名格式中,因此任何人都可以验证签名。此方法不保守消息的机密;若要使消息保密,还必须对消息进行加密。

    .NET Framework 提供以下实现数字签名算法的类:

    DSACryptoServiceProvider
    RSACryptoServiceProvider

    CA证书 Public Key Certificates(参考这里

    A public key certificate provides a safe way for an entity to pass on its public key to be used in asymmetric cryptography. The public key certificate avoids the following situation: if Charlie creates his own public key and private key, he can claim that he is Alice and send his public key to Bob. Bob will be able to communicate with Charlie, but Bob will think that he is sending his data to Alice.

    A public key certificate can be thought of as the digital equivalent of a passport. It is issued by a trusted organization and provides identification for the bearer. A trusted organization that issues public key certificates is known as a certificate authority (CA). The CA can be likened to a notary public. To obtain a certificate from a CA, one must provide proof of identity. Once the CA is confident that the applicant represents the organization it says it represents, the CA signs the certificate attesting to the validity of the information contained within the certificate.

    A public key certificate contains several fields, including:

    Issuer - The issuer is the CA that issued the certificate. If a user trusts the CA that issues a certificate, and if the certificate is valid, the user can trust the certificate.

    Period of validity - A certificate has an expiration date, and this date is one piece of information that should be checked when verifying the validity of a certificate.

    Subject - The subject field includes information about the entity that the certificate represents.

    Subject's public key - The primary piece of information that the certificate provides is the subject's public key. All the other fields are provided to ensure the validity of this key.

    Signature - The certificate is digitally signed by the CA that issued the certificate. The signature is created using the CA's private key and ensures the validity of the certificate. Because only the certificate is signed, not the data sent in the SSL transaction, SSL does not provide for non-repudiation.
    If Bob only accepts Alice's public key as valid when she sends it in a public key certificate, Bob will not be fooled into sending secret information to Charlie when Charlie masquerades as Alice.

    Multiple certificates may be linked in a certificate chain. When a certificate chain is used, the first certificate is always that of the sender. The next is the certificate of the entity that issued the sender's certificate. If there are more certificates in the chain, each is that of the authority that issued the previous certificate. The final certificate in the chain is the certificate for a root CA. A root CA is a public certificate authority that is widely trusted. Information for several root CAs is typically stored in the client's Internet browser. This information includes the CA's public key. Well-known CAs include VeriSign, Entrust, and GTE CyberTrust.
     

    哈希值
    哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希计算都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的。

    消息身份验证代码 (MAC) 哈希函数通常与数字签名一起用于对数据进行签名,而消息检测代码 (MDC) 哈希函数则用于数据完整性。

    双方(小红和小明)可按下面的方式使用哈希函数来确保数据的完整性。如果小红对小明编写一条消息并创建该消息的哈希,则小明可以在稍后散列该消息并将他的哈希与原始哈希进行比较。如果两个哈希值相同,则该消息没有被更改;如果值不相同,则该消息在小红编写它之后已被更改。为了使此系统发挥作用,小红必须对除小明外的所有人保密原始的哈希值。

    When sending encrypted data, SSL typically uses a cryptographic hash function to ensure data integrity. The hash function prevents Charlie from tampering with data that Alice sends to Bob.

    A cryptographic hash function is similar to a checksum. The main difference is that while a checksum is designed to detect accidental alterations in data, a cryptographic hash function is designed to detect deliberate alterations. When data is processed by a cryptographic hash function, a small string of bits, known as a hash, is generated. The slightest change to the message typically makes a large change in the resulting hash. A cryptographic hash function does not require a cryptographic key. Two hash functions often used with SSL are Message Digest 5 (MD5) and Secure Hash Algorithm (SHA). SHA was proposed by the US National Institute of Science and Technology (NIST).
     

    Message Authentication Code: A message authentication code (MAC) is similar to a cryptographic hash, except that it is based on a secret key. When secret key information is included with the data that is processed by a cryptographic hash function, the resulting hash is known as an HMAC.
    If Alice wants to be sure that Charlie does not tamper with her message to Bob, she can calculate an HMAC for her message and append the HMAC to her original message. She can then encrypt the message plus the HMAC using a secret key she shares with Bob. When Bob decrypts the message and calculates the HMAC, he will be able to tell if the message was modified in transit. With SSL, an HMAC is used with the transmission of secure data.


    .NET Framework 提供以下实现数字签名算法的类:

    HMACSHA1
    MACTripleDES
    MD5CryptoServiceProvider
    SHA1Managed
    SHA256Managed
    SHA384Managed
    SHA512Managed

    摘要函数(MD2、MD4和MD5,还有SHA1等算法(产生一个20字节的二进制数组))
    摘要是一种防止改动的方法,其中用到的函数叫摘要函数。这些函数的输入可以是任意大小的消息,而输出是一个固定长度的摘要。摘要有这样一个性质,如果改变了输入消息中的任何东西,甚至只有一位,输出的摘要将会发生不可预测的改变,也就是说输入消息的每一位对输出摘要都有影响。总之,摘要算法从给定的文本块中产生一个数字签名(fingerprint或message digest),数字签名可以用于防止有人从一个签名上获取文本信息或改变文本信息内容。摘要算法的数字签名原理在很多加密算法中都被使用,如S/KEY和PGP(pretty good privacy)。


    现在流行的摘要函数有MD4和MD5。MD2摘要算法的设计是出于下面的考虑:利用32位RISC结构来最大其吞吐量,而不需要大量的替换表(substitution table)。MD4算法将消息的给予对长度作为输入,产生一个128位的"指纹"或"消息化"。要产生两个具有相同消息化的文字块或者产生任何具有预先给定"指纹"的消息,都被认为在计算上是不可能的。MD5摘要算法是个数据认证标准。MD5的设计思想是要找出速度更快但更不安全的MD4中潜在的不安全,MD5的设计者通过使MD5在计算上慢下来,以及对这些计算做了一些基础性的改动来解决这个问题。MD5在RFC1321中给出文档描述,是MD4算法的一个扩展。美国国家标准技术研究所的SHA1和麻省理工学院Ronald Rivest提出的MD5是为代表。HMAC-MD5算法(消息摘要5)基于RFC1321。MD5对MD4做了改进,计算速度比MD4稍慢,但安全性能得到了进一步改善。MD5在计算中使用了64个32位常数,最终生成一个128位的完整性检查和。

    HMAC-SHA算法:安全Hash算法定义在NIST FIPS 180-1,其算法以MD5为原型。SHA在计算中使用了79个32位常数,最终产生一个160位完整性检查和。SHA检查和长度比MD5更长,因此安全性也更高。

    随机数生成
    随机数生成是许多加密操作不可分割的组成部分。例如,加密密钥需要尽可能地随机,以便使生成的密钥很难再现。加密随机数生成器必须生成无法以计算方法推算出(低于 p < .05 的概率)的输出;即,任何推算下一个输出位的方法不得比随机猜测具有更高的成功概率。.NET Framework 中的类使用随机数生成器生成加密密钥。

    在商务领域的应用

    许多人都知道NETSCAPE公司是Internet商业中领先技术的提供者,该公司提供了一种基于RSA和保密密钥的应用于因特网的技术,被称为安全插座层(Secure Sockets Layer,SSL)。

    也许很多人知道Socket,它是一个编程界面,并不提供任何安全措施,而SSL不但提供编程界面,而且向上提供一种安全的服务,SSL3.0现在已经应用到了服务器和浏览器上,SSL2.0则只能应用于服务器端。

    SSL3.0用一种电子证书(electric certificate)来实行身份进行验证后,双方就可以用保密密钥进行安全的会话了。它同时使用“对称”和“非对称”加密方法,在客户与电子商务的服务器进行沟通的过程中,客户会产生一个Session Key,然后客户用服务器端的公钥将Session Key进行加密,再传给服务器端,在双方都知道Session Key后,传输的数据都是以Session Key进行加密与解密的,但服务器端发给用户的公钥必需先向有关发证机关申请,以得到公证。

    基于SSL3.0提供的安全保障,用户就可以自由订购商品并且给出信用卡号了,也可以在网上和合作伙伴交流商业信息并且让供应商把订单和收货单从网上发过来,这样可以节省大量的纸张,为公司节省大量的电话、传真费用。在过去,电子信息交换(Electric Data Interchange,EDI)、信息交易(information transaction)和金融交易(financial transaction)都是在专用网络上完成的,使用专用网的费用大大高于互联网。正是这样巨大的诱惑,才使人们开始发展因特网上的电子商务,但不要忘记数据加密。
     

    SSL(Secure Sockets Layer) or TSL (Transport Layer Security)

    Secure Sockets Layer (SSL) is the most widely used protocol for implementing cryptography on the Web. SSL uses a combination of cryptographic processes to provide secure communication over a network. This section provides an introduction to SSL and the cryptographic processes it uses.

    SSL provides a secure enhancement to the standard TCP/IP sockets protocol used for Internet communications. As shown in the "TCP/IP Protocol Stack With SSL" figure below, the secure sockets layer is added between the transport layer and the application layer in the standard TCP/IP protocol stack. The application most commonly used with SSL is Hypertext Transfer Protocol (HTTP), the protocol for Internet Web pages.

    SSL was developed by Netscape in 1994, and with input from the Internet community, has evolved to become a standard. It is now under the control of the international standards organization, the Internet Engineering Task Force (IETF). The IETF has renamed SSL to Transport Layer Security (TLS), and released the first specification, version 1.0, in January 1999. TLS 1.0 is a modest upgrade to the most recent version of SSL, version 3.0. The differences between SSL 3.0 and TLS 1.0 are minor.

    One of the reasons SSL is effective is that it uses several different cryptographic processes. SSL uses public key cryptography to provide authentication, and secret key cryptography and digital signatures to provide for privacy and data integrity. Before you can understand SSL, it is helpful to understand these cryptographic processes.

    常用算法比较

    数据加密标准(DES)是一个古老的对称密钥加密算法,目前已经不再使用。它不是一个很安全的算法。

    三重DES(Triple-DES)仍然是很安全的,但是也只是在别无他法的情况下的一个较好的选择。显然高级加密标准(AES)是一个更好的加密算法,NIST用AES代替Triple-DES作为他们的标准(下面有更详细的讨论)。其他较好的算法包括另外两个AES的变种算法Twofish和Serpent-也称为CAST-128,它是效率和安全的完美结合。这几个算法不仅比DES更安全,而且也比DES的速度更快。为什么要使用一些又慢又不安全的算法呢

    SHA1是一个哈希函数,而不是一个加密函数。作为一个哈希函数,SHA1还是相当优秀的,但是还需要几年的发展才能用作加密算法。如果你正在设计一个新系统,那么谨记你可能会在若干年后用SHA1代替目前的算法。我再重复一遍:只是可能。

    RSA是一个公开密钥加密算法。RSA的密钥长度一般为2048-4096位。如果你现在的系统使用的是1024位的公开密钥,也没有必要担心,但是你可以加长密钥长度来达到更好的加密效果。

    高级加密标准(AES)是一个用来代替数据加密标准(DES)的算法。目前使用的一般为128,196和256位密钥,这三种密钥都是相当安全的。而且美国政府也是这样认为的。他们批准将128位密钥的AES算法用于一般数据加密,196位和256位密钥的AES算法用于秘密数据和绝密数据的加密。

    DESX是DES的一个改进版本。DESX的原理是利用一个随机的二进制数与加密前的数据以及解密后的数据异或。虽然也有人批评这种算法,但是与DES相比DESX确实更安全,不过DESX在许多情况下并不适用。我曾经处理过一个硬件支持DES的系统,由于有些环节不能容忍三重DES的慢速,我们在这些地方使用了DESX来代替DES。然而,这是一个非常特殊的情况。如果你需要使用DESX,理由显而易见(可能和我不得不使用DESX的原因类似)。但我建议你使用AES或者上面我提到的一些算法。

    RC4是一种常用于SSL连接的数据流加密算法。它已经出现很多年了,而且有很多已知和可能的缺陷,因此在一些新的工程中不要使用它。如果你目前正在使用它而且可以轻易的卸载它,那么情况也不是很坏。不过,我怀疑如果你现在正在使用它,你不可能轻易的卸载它。如果不能将它从系统中轻易的卸载,那么你还是考虑今后怎样升级它,但是不要感到很惊慌。我不会拒绝在一个使用RC4算法来加密SSL连接的网站购买东西,但是如果我现在要新建一个系统,那么我会考虑使用其他的算法,例如:AES。

    对于下面两个算法MD5-RSA和SHA1-DSA,他们是用于数字签名的。但是不要使用MD5,因为它有很多缺陷。很多年前大家就知道MD5中存在漏洞,不过直到今年夏天才破解出来。我们可以将SHA1和RSA或DSA配合在一起使用,目前DSA的密钥位数高达1024位,这个密钥位数已经足够长了,因此不需要担心安全问题。然而,如果NIST实现了更长的密钥位数当然更好。

    X.509证书是一个数据结构,常用于规定比特和字节的顺序,它本身不是一个密码系统。它通常包含一个RSA密钥,也可能包含一个DSA密钥。但是X.509证书内部以及证书本身并不是加密技术。