主頁 > 軟體設計 > 認證系統設計經典會話

認證系統設計經典會話

2020-09-10 18:41:37 軟體設計

Bill Bryant,首次寫與1988年2月
Theodore Ts'o與1997年2月整理并轉換成HTML,并且追加了 afterword 章節來描述V5版本的一些變化

前言

本文虛構了一個關于公網認證系統--Charon構建程序的對話,隨著對話的進行,Athena和Euripides探討了公共網路環境里普遍存在安全問題,并在Charon系統設計之初就考慮好了這些問題的解決方式,所以直到對話完成,Athena和Euripides才算真正的把系統設計好,

當系統設計好后,Athena把系統的名字從Charon改成了Kerberos,非常巧合的是,在MIT的一個專案--Athena中,設計和實作的認證系統名稱就叫做Kerberos,

對話中的“Kerberos”與1988年發表的“Kerberos:一個公共網路的認證系統“有著驚人的相似之處,

Scene I

在一個小隔間里,Athena和Euripides正在兩個相鄰的終端上作業

Athena:Rip,你們這個分時共享系統就是個累贅,因為其他人都登陸著,它慢的使我根本沒法成我的作業,

Euripides:這個不要向我抱怨,我只是個打工的,

Athena:難道你不知道我們的需求嗎?我們真正想要的是給每個人一個自己的作業站,之后再用網路鏈接所有的作業站,從而使大家能相互通信,這樣他們就不用擔心共享計算周期的問題,

Euripides:那么我們需要多少作業站呢,1000個?

Athena:差不多

Euripides:哪你有沒有調研過普通作業站的磁盤,一般來講是沒有足夠的空間來安裝你在共享機器上所有的軟體的?

Athena:這個我已經想好了,我們可以把所需的軟體裝在不同的服務器上,當你登陸到自己的作業站后,你可以通過網路向這些服務器發請求來使用那些軟體服務,這樣還能使所有的作業站都使用相同的軟體版本,軟體升級也會很便捷,只用把服務器上的軟體升級就可以了,不用到每個作業站上面去操作,

Euripides:好吧,但是你怎么管理個人檔案呢?在分時共享系統中,我可以通過任意一個和系統連接的終端登陸并訪問我自己的檔案,你這樣設計后,我是否能通過任意作業站來獲取我的個人檔案,還是說我要隨身帶個軟盤來保存我自己的檔案呢?

Athena:我想我們可以用另外一臺服務器來存盤私有檔案,這樣你就可以登陸任意的作業站來獲取你自己的檔案,

Euripides:那列印功能怎么辦,難道讓每個作業站都要有自己的列印機嗎?你用誰的錢來買這些設備呢?還有電子郵件怎么處理,怎么把郵件分發到所有的作業站上呢?

Athena:嗯…,很明顯,我們沒有錢給每個作業站配置一臺列印機,但是我們可以用一臺機器專門用來做列印服務,你把你的列印任務發給列印服務機,由它來幫你列印,你也可以用同樣的思路來處理電子郵件,由一臺機器專門做郵件服務,如果你想要你的郵件,你連接這個服務,由他來把你的郵件挑揀出來,

Euripides:你的作業站系統聽起來是很好,當我有了自己的作業站,你知道我會做什么嗎,我會找出你的名字,并使我的作業站認為我是你,這樣我就可以連接到郵件服務獲取你的郵件,我還可以連上檔案服務器來洗掉你的檔案,我還可以…

Athena:你真的會這樣做嗎?

Euripides:是的,那些服務怎么能知道現在是我在操作而不是你呢?

Athena:呃,我不知道,我需要好好想想這個問題,

Euripides:聽起來是的,如果你知道怎么做了請一定告訴我,

Scene II

第二天早上,在Euripides 的辦公室,Euripides正在他的辦公桌前讀他的點子郵件,Athena敲門進來

Athena:哈哈,我已經找到一種方式來加密網路環境,從而阻止像你這樣調皮的家伙不能偽裝成別人來使用那些服務,

Euripides:真的嗎,坐下來講吧,

Athena:在我開始之前,我能不能給我們的討論定下一個基本準則?

Euripides:什么準則?

Athena:假如我說了下面的話:“我想看我的電子郵件,所以我連接上郵件服務,告訴郵件服務把郵件發到我的作業站,”實際上,并不是我直接連接郵件服務,而是我使用了一個程式去連接郵件服務,一個稱作郵件服務客戶端的程式,
但是當我每次描述用戶和服務互動時,我不會說“客戶端做了什么“,而是會說“我做了什么”,所以請記住是客戶端作為我的代理做了這些事,我這樣講有沒有問題?

Euripides:沒有問題,

Athena:針對網路安全問題,最笨的方式是每次郵件服務都讓用戶提供密碼來證明用戶身份,

Euripides:這的確是夠笨的,在這樣一個系統中,需要每一個服務都知道你的密碼,如果網路里面有一千個用戶,每個服務都要有一千個用戶的密碼;當你想要修改密碼時,你還得聯系所有的服務去一個個修改,我想你的系統不會這么笨吧,

Athena:我的系統不笨,他像這樣作業:不僅僅是用戶有密碼,服務也有密碼,每個用戶知道自己的密碼,每個服務也知道自己的密碼,并且還有一個認證服務知到所有的密碼,包括用戶的和服務的,認證服務把這些密碼存盤在一個中央倉庫中,

Euripides:你有給這個認證服務起好名字嗎?

Athena:我還沒有想好,你有什么想法嗎?

Euripides:那個幫助死者過冥河的擺渡人名字怎么樣?

Athena:Charon嗎?

Euripides:是的,就是他,除非你證明你的真實身份,否則他是不會擺渡你的,

Athena:Rip,你又來這一套,重新杜撰羅馬神話,Charon并不關系你的身份,他只確保你已經死掉就夠了,

Euripides:哪你有沒有一個更好的名字?

Athena:沒,還沒有,

Euripides:那就把這個認證服務叫“Charon ”吧,

Athena:好吧,那我就開始描述這個系統了,

我們假定你現在要用郵件服務,在這個系統里,你不能直接使用一個服務,除非Charon告訴那個服務你就是你所宣告的那個人,并且除非你先向Charon認證,否則你也不能獲取到那個服務,當你向Charon認證時,你同時得告訴Charon你想使用哪一個服務,就是說如果你想用郵件服務,你得明確告訴Charon,

接著,Charon要求你提供認證資訊,你向Charon提供你的密碼,然后Charon和注冊在中央資料庫中的密碼進行對比,如果密碼時匹配的,Charon認為你證實了你的身份,

接下來,Charon要告訴郵件服務你就是你所宣告的那個人,因為Charon知道所有服務的密碼,當然也包括郵件服務的,很明顯Charon可以告訴你郵件服務的密碼,當你向郵件服務發起請求時你可以用這個密碼證明你已經向Charon認證過了,

現在的問題是,Charon不能直接給你密碼,因為你知道這個密碼后,下一次你想訪問郵件服務,你就可以繞過Charon不用再認證了,之后你仍可以偽裝別人,用別人的名字來訪問郵件服務獲取他的郵件了,

所以,Charon會給你一個郵件服務的票據(TICKET)而不是直接給你密碼,這個票據里面包含了你的名字,并且會利用郵件服務的密碼進行加密,

TICKET = {username} K_server

  • {X}K_Y 表示 用K_Y對X進行加密,

拿到票據后,你現在可以向郵件服務請求你的郵件了,你告訴郵件服務你的名字,同時把票據發給郵件服務來證明你的身份,

郵件服務拿到票據后,首先用自己的密碼進行解碼,如果能正常解碼,郵件服務就能拿到Charon存放在票據中的名字,

郵件服務再用票據中的名字和你提供的名字進行對比,如果名字一致,郵件服務就認為你是你所宣告的人,就把你的郵件給你,

你覺得這個方法怎樣?

Euripides:我有幾個問題,

Athena:預料之中,你繼續講,

Euripides:當一個服務解碼一個票據,他如何判斷自己正確解碼了(這個票據是針對自己這個服務的,而不是用戶申請訪問別的服務對應的票據)?

Athena:這個我還沒考慮好,

Euripides:最好能把服務的名字也放到票據中,這樣當一個服務解碼票據后,他可以通過能不能在票據中正確找到自己的名字來判斷解碼是否成功,

Athena:聽起來不錯,那么現在票據就變成了這樣

TICKET - {username: servicename} K_server

Euripides:這樣票據就包含用戶名和服務名,

Athena:再用服務的密碼進行加密,

Euripides:可是我還是不認為這些資訊就能保證票據的安全性,

Athena:舉個例子呢,

Euripides:比如說,你向Charon要了一個郵件服務的票據,Charon準備好了票據,并把你的名字“tina”放了進去,假定在Charon通過網路把票據發給你的程序中我把這個票據復制了一份,然后我欺騙我的作業站說我就是tina,這樣作業在我作業站的郵件客戶端程式就會認為我就是你,利用你的名字,郵件客戶端再利用偷來的票據向郵件服務發請求,這樣郵件服務收到請求后解碼了票據,并會驗證通過,郵件服務就會把你的服務發給我,

Athena:嗯,是的,這個設計還是不完美,

Euripides:但是我知道一種方式來修復這個問題,或者說區域解決這個問題,我認為Charon需要在票據中包含更多的資訊,除了用戶名,Charon還需要把用戶請求票據時的網路地址包含進去,這樣就可以多一個安全保證,

我用下面的程序來證明:假如說我現在偷取了你的票據,這個票據里面有你作業站的地址,這個地址和我作業站的地址是不一樣的,當我偽造你的名字和偷來的票據請求郵件服務時,郵件服務從票據中解碼出名字和地址并和請求中的用戶名和地址進行匹配,雖然用戶名匹配成功了,但是地址不匹配,很明顯這個票據被偷了,服務器就拒絕這次請求,

Athena:太好了,我希望我也能想到這樣的方法,

Euripides:哈,這就是我的目的,

Athena:那么修改后的票據就變成了

TICKET = {username:ws_address:servicename} K_server

Athena:我現在好興奮,讓我構建一個Charon系統來看看他是否能作業吧,

Euripides:還不能這么快,我對這個系統還有幾個疑問,

Athena:好吧,繼續,

Euripides:目前來看,每次只要我想訪問一次服務,我都得獲取一個票據,如果我一整天都在作業,我肯定會多次要獲取我的郵件資訊,如果每次訪問服務都得獲取一個票據,那我是不會喜歡這個系統的,
Athena:呃…,為什么票據不能重復使用呢,當你獲取一個票據后,你是可以重復使用的,比方說,當郵件客戶端程式向服務請求時,他把票據復制一份,把這個副本發送到服務端,

Euripides:聽起來不錯,但是還是有問題,目前來看,當我要訪問一個我還沒有票據的服務時,我都得向Charon提供我的密碼,例如我想訪問我的檔案,我得向Charon提供我的密碼來獲取一個票據,當我想向郵件服務獲取我的郵件時我還得向Charon提供我的密碼,假如我又想列印些什么東西,我又得訪問Charon,你能想象到那個畫面的,

Athena:呃,是的,

Euripides:這還不是最糟的,目前你向Charon認證時,你以明文的形式在網路上傳播你的密碼,那些像你這樣聰明的人肯定可以通過模擬網路來偷取別人的密碼,如果我有了你的密碼,我又可以以你的名義使用任意服務,

Athena:這些都是嚴重的問題,我需要重新設計一下,

Scene III

隔天早上,Athena在咖啡間遇見了Euripides,并在他的接滿水后,把手搭在了他的肩膀上,一起向咖啡機走去

Athena:我想了一個新版本的Charon可以解決我們的問題,

Euripides:真的嗎,這么快?

Athena:嗯,這個問題讓我想了一晚上,

Euripides:這一定是你的負罪感,讓我們找個小隔間再討論討論吧?

Athena:為什么不呢?

兩人走向一個小隔間

Athena:作為開始部分,我會重新陳述一下我們的問題,看看我們的系統是不是真的需要這些功能,

Athena:第一個需求:用戶只用在他們登陸進作業站的時候輸入他們的密碼一次,這個需求指的是你不用在每次獲取其他服務的票據時都要輸入密碼,第二個需求:密碼不能以明文的形式在網路上傳播,

Euripides:是的

Athena:對于第一個需求:你只需要輸入一次你的密碼,為了滿足這個需求,我會引入一個新的服務,一個叫做“票據分發”(ticket-granting)服務,當用戶向Charon認證完成后,這個服務就會向這個用戶分發票據,如果你有這個票據分發服務的票據(TGT),你就可以使用這個票據分發服務,
票據分發服務可以簡單當作是Charon的一個變體,他也能訪問中央資料庫,Charon中的這個票據分發服務可以讓你用票據代替密碼來認證,

現在,認證系統將這樣作業:你登陸到你的作業站,然后利用Kinit這個程式來連接Charon服務,之后你向Charon提供憑據,Kinit從Charon服務獲取你對應的TGT,

假如現在你想要訪問郵件服務,而你還沒有郵件服務的票據,你就可以用TGT向Charon來獲取郵件服務的票據,而不是使用密碼來獲取這個票據,

Euripides:那我需要訪問其他服務時要不要每次都得獲取一個新的TGT呢?

Athena:不用,記不記得上次我們達成的共識,票據是可以重復使用的,一旦你有一個TGT,你不需要再獲取一個,之后你就可以重復使用這個TGT來獲取其他服務的票據,

Euripides:嗯,很有道理,因為你可以重復使用票據,所以一旦票據分發服務給你一個針對特定服務的票據(ST),就不需要再獲取這票據了,

Athena:是的,這樣是不是比較簡潔,

Euripides:嗯,到目前為止還行,只要在獲取TGT時不通過明文在網路上傳輸我的密碼,

Athena:就像我說的,我這問題我也解決了,事實上,當向Charon請求TGT時,我表述的好像是我要通過網路發送你的密碼,但這并不是必須的,

真實情況是,當用Kinit程式向Charon獲取TGT時,kinit并不向Charon服務發送密碼,kinit只發送你的名字,

Euripides:好

Athena:Charon服務利用你的名字來查找你的密碼,接著Charon構造一個包含TGT的資料包,在Charon把這個資料包發給你之前,他會用你的密碼對資料包進行加密,

你的作業站收到這個資料包后,提示你輸入密碼,kinit會嘗試用你輸入的密碼來解碼這個資料包,如果解碼成功,預示著你認證成功,并且你會擁有TGT,然后你可以用這個票據來獲取你想要服務的票據,

這個是不是你所想要的?

Euripides:我還不清楚,我需要再考慮考慮,我認為你剛才描述的那部分系統功能作業的相當好,它只需要我認證一次,此后Charon會自動的為我分發其他服務的票據也不用我再關心,但是關于票據的設計我還是有困惑,因為基于一個前提,那就是票據是可重復用的,我同意票據可以重復使用,但是可重復用本質上講是危險的,

Athena:具體來說呢

Euripides:打比方來說,假如你使用了一個不安全的作業站,期間你獲取了郵件服務的票據、列印服務的、檔案服務的,然后你退出了作業站,

現在假定我也登陸到了這個作業站,并且找到了這些票據,我呢,又比較喜歡制造麻煩,所以我把我的名字改成你的來欺騙作業站說我就是你,因為那些票據都是用你的名字生成的,所以我可以用郵件客戶端來獲取你的郵件,也能獲取你的檔案,也能用你的賬號發送成千上萬的列印任務,所有的這一切都是因為你把票據忘在了這個作業站上,

并且也沒有什么方法能阻止我把這些票據再復制下來,這樣我就可以一直使用它們了,

Athena:這個很好解決呀,我們可以寫一段程式在用戶登出時銷毀用戶的票據,這樣你就不能使用了,

Euripides:好吧,很明顯你的系統需要一個銷毀程式,但是讓用戶依賴于這樣一個程式是愚蠢的,你不能確保用戶在每一次使用完作業站登出時都執行這個銷毀程式,即便你依賴于用戶執行銷毀程式,在下面的場景下也有問題

我寫了一個程式,它可以監聽網路,當有服務票據從網路上傳播時我就把它復制下來,假如我想陷害你,當你登陸進作業站時,我也把這個程式打開,從而能copy你的票據,

當你完成作業退出作業站并離開后,我把我的作業站地址篡改成你的地址,更改用戶名使我的作業站相信我就是你,這樣我就有了你的票據,你的名字,你的地址,我又可以以你的名義重新使用這些票據,

即便是你在登出時銷毀了你的票據也沒有關系,因為我偷的這些票據只要我想用就會一直有效,而這都是因為你現在的票據設計里面并沒有對票據的使用次數或者使用時間做限制,

Athena:哦,我知道你所說的了,票據永久有效是一個大的安全隱患,我們必須限制一個票據可用的最大時長,也許我們可以給每個票據一些過期資訊,

Euripides:實際上,我認為每個票據都得追加下面的資訊:一個有效期(lifespan)欄位,表明這個票據的最大有效時間;還有一個時間戳(timestamp)欄位,表明Charon創建這個票據的時間,所以現在票據資訊就變成了

TICKET = {username:ws_address:servicename:lifespan:timestamp} K_server

Euripides:現在當一個服務解碼票據之后,首先檢查下票據里面的用戶名和地址和用戶發過來的是否一致,接著再用有效期和時間戳欄位判斷這個票據是否過期,

Athena:很好,那這個有效期設定多久比較好呢?

Euripides:我也不清楚,設定成大多數作業站的會話時長怎么樣,即8小時?

Athena:這也就是說,如果我在我的作業站作業超過8小時,我所有的票據都將失效,也包括票據分發票據,所以在8小時后,我必須再次向Charon認證,

Euripides:這個也不是難以接受的吧?

Athena:嗯,也是,那我們就定下來票據在8小時后過期,現在我有一個新的疑問了,假如我從網路上復制了你的票據..

Euripides:哦,Tina,你不會真的這樣做吧,對不對,

Athena:這只是我們交談的一種假設情況,現在我復制了你的票據,并等著你退出你的作業站,可能是你和醫生有一個約談或者是要參加一個會議,所以你在兩個小時左右就退出了你的作業站,雖然你比較謹慎的在推出時銷毀了你的票據,但是我已經偷取了這些票據,并且在接下來的6個小時里面它們是完好可用的,我將有足夠的時間來操作你的檔案,以你的名義發送成千上萬的列印任務,

所以說,追加有效期和時間戳的方式對于票據過期后的攻擊是起作用的,但是如果在票據過期前攻擊那,,

Euripides:哦,是的,你是對的,

Athena:我想我們找到核心問題了,

Euripides:我猜你今天晚上又要忙活了,要去喝些咖啡嗎?

Athena:要的,走

Scene IV

隔天早上,在Euripides的辦公室,Athena敲門進來

Euripides:Tina,一大早就戴著個黑眼圈呀,

Athena:是啊,你知道又一個漫漫長夜,

Euripides:你找到解決問題的方法了嗎?

Athena:我想我找到了,

Euripides:坐下來慢慢說,

Athena:按慣例,首先我要重述下這個問題:票據都有一個有效期-8小時,如果在過期前其他人偷走了你的票據,那我們就沒有辦法阻止他了,

Euripides:正是這個問題

Athena:如果我們把票據設計成不可重復使用,那我們可以修復這個問題

Euripides:但是這樣你就不得不在每次想要利用一個網路服務的時候都去請求一個票據了

Athena:是的,這算是一種粗暴的解決方案,哦,我該怎么繼續我的論述呢?
好吧,讓我們從需求的角度再把問題重述一下:一個服務必須要證明現在用票據發起請求的人就是Charon分給票據的那個人,

讓我們再把認證程序推演一遍,看我能否想出一個合適的方法來表述我的解決方案,

當我想訪問一個特定的服務時,第一步,我在我的作業站上啟動一個客戶端程式,這個客戶端發送三個資訊給服務,我的名稱、地址、以及相應的票據,其中票據中包含認證時的用戶名,認證時作業站對應的網路地址,還包含了票據的過期資訊,所有這些資訊在回傳給客戶端時Charon都用對應服務的密碼進行了加密,

我們現在的認證模式基于下面的測驗:

  • 服務能否解碼對應的票據
  • 票據是否過期
  • 票據中的用戶名和網路地址是否和票據一起發送的用戶名和地址匹配

這些測驗能證明什么呢?

第一,這個票據是否是Charon分發的,如果票據不能正確解碼,那就不是從真正的Charon過來的,真正的Charon會使用服務對應的密碼加密,而只有Charon和服務知道這個服務的密碼,如果票據能正常解碼器,那服務就能確定票據是從真正的Charon過來的的,這樣就能防止攻擊者偽造Charon分發票據,

第二,這個票據是否過期,如果過期,服務端就拒絕這個請求,這樣能阻止攻擊者使用舊的票據,因為這些票據很有可能被偷走了,

第三,檢查票據中的用戶名和網路地址,如果檢查失敗,說明用戶在使用別人的票據(可能是偷偷在用),服務端肯定要拒絕這樣的請求,

如果用戶名和地址匹配上,那證明了什么呢?什么也沒有,攻擊者可以從網路上偷走票據,更改他的作業站地址和用戶名,從而偷竊別人的資源,就像我昨天說的,票據在過期之前是可以無限制的重用的,它們能被重用是因為服務端沒辦法區分現在請求的用戶是否是票據真正的擁有者,

服務端不能做區分是因為他和用戶之間沒有一個共享的機密資訊,打比方來說,我在Elsinore(哈姆雷特里面的城堡)站崗,現在你要來換下我,除非你告訴我正確的暗號,否則我是不會同意你替換我的,這就是我們兩個之間需要共享一個機密的例子,這個機密可能是某個人為所有的站崗者想出的暗號,
這就是我昨天晚上想的,為什么不能讓Charon為票據真正的擁有者和服務生成一個共享的密碼呢?Charon把這個會話密鑰(session key 就是剛說的共享密碼)的一份拷貝發給服務端,再把另一份拷貝發給用戶,當服務端收到用戶的請求時,他可以用這個會話密鑰來驗證用戶,

Euripides:等一下,Charon怎么給服務端和用戶發送這個密鑰呢?

Athena:Charon把會話密鑰作為回傳值的一部分,像這樣:

CHARON REPLY = {sessionkey|ticket} K_user

服務端通過解碼票據來獲取會話密鑰,所以現在票據變成了如下的樣子

TICKET = {sessionkey:username:address:servicename:lifespan:timestamp}K_server

現在當你想要訪問一個服務時,你使用的客戶端程式會構建一個我們稱之為“認證物件”(AUTHENTICATOR),這個認證物件中包含你的用戶名和你作業站的網路地址,客戶端用Charon回傳的會話密鑰對認證物件進行加密,就是他向Charon認證時對應的會話密鑰,

AUTHENTICATOR - {username:address} K_session

客戶端構造好認證物件后,和票據一起發送到服務端,這時服務端還不能解碼這個認證物件,因為他還沒有拿到回話密鑰,密鑰存放在票據中,所以第一步服務端必須先解碼票據

服務端解碼票據后將獲取下面的資訊:

  • 票據有效時間和創建時間
  • 票據擁有者的名字
  • 票據擁有者對應的網路地址
  • 會話密鑰

服務端先檢查票據是否過期,如果是好的,接著,服務端用會話密鑰解碼對應的認證物件,如果能順利解碼,服務端就會獲取到用戶名和網路地址,然后服務端把獲取到的用戶名和網路地址和票據中的對應資訊比較,并且再和發送票據、認證物件時一起發送過來的用戶名和網路地址比較,如果一切都對比正確,則服務端就可以確認現在發送票據的人確實是票據的擁有者

我認為會話密鑰-認證物件能解決票據重用帶來的問題

Euripides:可能吧,我還是有困惑,要想用這個方式,我必須構建服務相應的認證物件

Athena:不,你不僅要有認證物件,還要有正確的票據,如果沒有票據只有認證物件是沒有任何意義的,因為沒有解碼票據前你是獲取不到會話密鑰的,而沒有會話密鑰你就沒法解碼認證物件,

Euripides:這個我知道,但是你也說了,當一個客戶端程式請求服務端時,他會把認證物件和票據一起發送過去

Athena:是的,我這樣說過

Euripides:如果真是這樣,那怎么阻止我把認證物件和票據同時偷走呢?我可以確定通程序式我能做到這個,如果我能同時偷取到認證物件和票據,這樣在票據過期前我就可以用這兩個資訊,改變我作業站的地址和用戶名來偽裝請求了,是不是?

Athena:是的,好失望

Euripides:等等,這沒什么大不了的,票據在過期之前可以重復使用,但這并不預示著認證物件也可以重復使用,假如我們設計一個方案只允許認證物件使用一次,是不是就沒有問題了

Athena:是的,很有可能,我們再討論一下這個程序,客戶端程式構建了一個認證物件,然后把它和票據一起發送給服務端,你把票據和認證物件都復制一份偷走了,但是這個票據和認證物件在你能發給服務端之前已經到達了服務端,如果認證物件只能夠使用一次,那你復制下來的票據和認證物件就不起效了,當你嘗試認證時就會失敗

好了,總算放心了,所以現在需要做的事是用一種方式保證認證物件只能使用一次

Euripides:沒有問題,讓我們在認證物件里面也存放一個有效期和生成時間,假如每一個認證物件的有效期只有幾分鐘,當你想使用一個服務時,你的客戶端程式構建一個認證物件,添加上當前的時間戳,接著把它發送到服務端,

服務端收到票據和認證物件后,先解碼票據獲取會話密鑰,然后用會話密鑰解碼認證物件,接著檢查認證物件是否過期,如果沒有,并且其他的檢查都通過,服務端通過認證,

假如現在我復制了你的票據和認證物件,為了使用它們,我需要在幾分鐘內修改好我的作業站網路和用戶名,這個要求是很高的,我不認為能做到,除非…

好吧,還有一個潛在的風險,假如我不是在當你向服務端認證時復制票據和認證物件,而是復制Charon發給你的原始資料包,就是你向Charon要票據時它回傳給你的資料包

這個資料包,包含了兩份會話密鑰在里面,一個給你,一個給服務端,給服務端的在票據里面,我不能拿到,但是另一個呢,那個你用來生成認證物件的密鑰呢

如果我能拿到這個密鑰,我就可以構建自己的認證物件,這樣我就可以攻破這個系統

Athena:這個我昨晚上也想到過,但是我推演了一下獲取票據的程序,發現以這種方式偷取認證物件是不可能的,

你坐在你的作業站前,用kinit程式獲取你的票據分發票據(TGT),kinit需要你的名字,你輸入后,kinit把它發送到Charon,

Charon用你的名字到資料庫中查詢你的密碼,接著創建一個TGT,作為這個程序的一部分,Charon創建一個你和票據分發服務共享的會話密鑰,Charon把這個密鑰的一份拷貝放到TGT中,把另一個拷貝放到資料包中,在把這個資料包發送給你之前,Charon會用你的密碼把它加密,

CHARON REPLY = [sessionkey|TGT] K_user

Charon通過網路把加密后的資料發給你,如果有人偷取了這個資料包,沒有你的密碼他沒法解碼這個資料包,也就不能獲取到會話密鑰,

Kinit獲取到這個資料包之后,提示你輸入密碼,如果你輸入了正確的密碼,Kinit就會解碼這個資料包,給你對應的會話密鑰,

客戶端為票據分發請求創建一個認證物件,并使用會話密鑰對認證物件加密,接著客戶端把這個加密后的認證物件發送給Charon,同時把TGT,你的名字,作業站的網路地址還有你要訪問的-郵件服務的名稱一起發過去,

票據分發服務(TGS)收到這些資訊,(其中TGT和普通的ST,也沒有區別,它就是票據分發服務對應的票據-ST,里面也是包含了{sessionkey:username:address:servicename:lifespan:timestamp}這些資訊,只不過服務名字就是固定的TGS的名字,并用票據分發服務對應的密碼進行了加密),就開始正常的認證檢查,(也是先用自己的密碼解碼TGT,看是否過期,再用里面的會話密鑰解碼認證物件,驗證用戶名,地址)如果檢查通過,票據分發服務(TGS)就會拿到一個正確的會話密鑰,接著票據分發服務為你構建一個郵件服務的票據,并為你和郵件服務創建一個新的共享的會話密鑰,

接下來,票據分發服務會準備一個發往你作業站的票據資料包,這個資料包中包含了剛創建的郵件服務的票據和新建的你和郵件服務共享的會話密鑰,在發送資料包之前,票據分發服務會用你和票據分發服務之間共享的會話密鑰把資料包加密,

現在看下郵件服務的票據包的發送,假如有人在這個資料包在網路上傳輸的工程中復制了一份,由于資料包用資料分發服務的會話密鑰加密過,他也得不到里面的內容,因而不能得到在資料包中的郵件服務的會話密鑰,沒有這個密鑰,他就不能創建認證物件,從而也不能使用TGS生成的并通過網路傳輸的郵件服務票據,

所以現在來看,我們安全了,你認為呢?

Euripides:可能吧

Athena:可能,你就只能說個這嗎

Euripides:別生氣,這只是對我自己刻薄的說法,你為這個都搞了大半夜了

Athena:Pthhhhh!

Euripides:好吧,是3/4個晚上,現在,這個系統聽起來可以接受了,會話密鑰的方式解決了昨晚上我思考的一個問題,一個雙向認證的問題,介意我再說幾分鐘嗎?

Athena:當然

Euripides:你真和善,昨晚上當會話密鑰和認證物件跳入的大腦時,我嘗試著找到系統的新問題,最后還真找到了一個嚴重問題,接下來我會用一個例子慢慢說明它:

假如說你厭倦了你現在的作業,并且也找到了新的感興趣的想跳槽過去,你想在公司的列印機上列印你的簡歷,使獵頭或者潛在的雇主能注意到你的優點,

所以你點擊了列印功能,直接把你的簡歷發送給相應的列印機,如果你還沒有列印服務的票據,列印客戶端首先會獲取列印服務的票據,再以你的名義把票據發送給服務端,至少在你認為它是按照這樣的流程來作業的,你并不知道這個任務是否發給了正確的列印機,

假如現在有一些惡意的黑客--你的老板--有一個轉換系統,利用這個系統,它能把你的請求和票據重定向到他辦公室的列印機上,如果他的這個列印機服務設計的不關心對應的票據和內容,它直接忽略掉票據,并回傳給你的作業站一個資訊說票據通過驗證,服務端也準備好為你提供列印服務了,你的列印客戶端發送列印命令給這個偽裝的列印機,這樣你的敵人就拿到了你的簡歷,

我用對比的方式重述下這個問題,就是在沒有會話密鑰和認證物件的時候,Charon能夠阻止服務端不被錯誤的用戶訪問,但是并不能阻止用戶訪問錯誤的服務端,系統需要一種方式能讓客戶端在發送敏感資訊給服務端前先驗證服務端的正確性,也就是說系統必須能雙向認證,

利用會話密鑰,只要你能正確設計客戶端程式,就可以解決掉這個問題,讓我們再以列印服務為例,我們希望列印客戶端能確認它發的列印服務確實是被正確的列印服務接收到的,

那么列印客戶端應該這樣做,我輸入一個列印任務和對應的列印檔案名-我簡歷的名稱,假如我擁有列印服務的票據和會話密鑰,客戶端程式用會話密鑰構建一個認證物件,把認證物件和票據發給認為正確的列印機,這時客戶端并沒有發送要列印的簡歷,他要等待服務端回傳資訊,
現在正真的列印服務接收到票據和認證物件,首先解碼票據獲取會話密鑰,接著用會話密鑰解碼認證物件,之后做各種認證檢查;

假如認證通過,服務端回傳給客戶端一個能證明自己身份的資料包給客戶端,并用會話密鑰把回傳的資料包加密,

客戶端收到資料包后會嘗試用會話密鑰解碼資料包,如果資料包正確解碼,并且得到了正確的服務端回傳資訊,客戶端就可以判定現在回傳資訊的是正確的列印服務,接著才會把對應的列印簡歷任務發過去,
這樣假定你的老板用轉換系統把他的列印機偽裝成我想用的那一臺,我的客戶端發送認證物件和票據給他并開始等待回傳結果,而偽裝的列印機不能生成正確的回傳資訊,因為它不能解碼票據得到會話密鑰,這時我的客戶端收不到正確的回傳資訊,就不會把真正的列印任務發過去,最終客戶端等待超時并退出,雖然我的列印任務沒有完成,但至少我的簡歷沒有出現在敵人的辦公桌上,

你看,我們有一個堅實的理論依據來實作Charon認證系統了,

Athena:是的,可不管怎么說,我并不喜歡Charon這個名字

Euripides:你不喜歡,從什么時候開始的

Athena:我一直都不喜歡,因為這個名字沒有任何意義,我之前跟我的叔叔談起這個事,他建議我用另一名字,Charon的那只有三個頭的狗

Euripides:哦,你是說“Cerberus”

Athena:注意你的發音,是“Cerberus”

Euripides:呃,是這個名字嗎?

Athena:是的,如果你是個羅馬人,我是一個希臘神,我有一個希臘看門狗,那么它的名字會讀作“Kerberos”,首字母是K

Euripides:好了好了,不要再扔霹靂了,就用這個名字了,事實上,他有一個漂亮的黑眼圈,現在,再見,Charon,你好,Kerberos,

Afterword

這個對話是在1988年寫的,用來幫助讀者理解為什么Kerberos V4版本設計成這個樣子,這么多年,它很好的完成了任務,

當我把這個對話整理成HTML后,我驚訝的發現這個檔案也同樣適用于V5版本,雖然很多事情發生了變化,但是協議的核心還是一樣的,只有兩個地方在V5版本中做了調整,

第一個變化是意識到如果一個黑客用程式來抓取票據和認證物件,并立即將它們發送到服務端,這樣把認證物件的有效期設定成5分鐘并不能有效的阻止這種重放攻擊,

所以在V5版本中,認證物件被真正設計成“只能使用一次”,這通過在服務端設計一個快取,用來保存最近發過來的認證物件的記錄來實作,攻擊者嘗試偷取認證物件并重用它,即便在5分鐘的視窗期里,服務端的快取也能區分出來這個認證物件已經被提交過了,

第二個主要變化是當用戶用Kinit首次從Kerberos獲取服務的票據(TGT)時,在Kerberos把票據回傳給客戶端時,票據不需要用用戶的密碼加密,因為這個票據已經用票據分發服務的密碼加密過了,之后用戶用這個票據再向Kerveros請求其他服務的票據時也是以未加密的形式直接在網路上傳播的,所以這個地方就沒有必要再用用戶的密碼去進行加密了(回傳資料包中的其他部分如票據會話密鑰等還是要加密的)

票據分發服務(TGS)也做了同樣的修改,票據分發服務生成的票據,也不再用票據分發服務對應的會話密鑰加密,因為這個票據已經用服務對應的密碼加密過了,
例如在V4版本中,資料包是下面這樣的

KDC_REPLY = {TICKET, client, server, K_session}K_user
TICKET = {client, server, start_time, lifetime, K_session}K_server

在V5版本中會變成下面的樣子

KDC_REPLY = TICKET, {client, server, K_session}K_user

最終的請求程序如下

當然,Kerberos在V5版本中還加入了其他的新特性,用戶可以安全的分發他的票據,從而在其他的地方使用;用戶也可以把部分權限授予一個服務器,使這個服務器可以作為自己的代理,其他的新特性包括用更加安全的加密演算法代替DES,例如triple-DES,讀者如果想了解更多關于V5和V4之間不同點的可以訪問【Kerberos系統的進化】,作者是 Cliff Neumann 和 Theodore Ts'o,

最后希望你能喜歡關于Kerveros的簡單介紹,祝你在之后的使用中一切順利,

Theodore Ts'o 1997.2

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/3087.html

標籤:架構設計

上一篇:論面向服務架構(SOA)設計及其應用

下一篇:Java 考試系統專案原始碼 springboot mybaits vue.js 前后分離跨域

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more