1. 程式人生 > >[轉帖]Kerberos簡介

[轉帖]Kerberos簡介

1.  Kerberos簡介

https://www.cnblogs.com/wukenaihe/p/3732141.html

1.1. 功能

  1. 一個安全認證協議

  2. 用tickets驗證

  3. 避免本地儲存密碼和在網際網路上傳輸密碼

  4. 包含一個可信任的第三方

  5. 使用對稱加密

  6. 客戶端與伺服器(非KDC)之間能夠相互驗證

Kerberos只提供一種功能——在網路上安全的完成使用者的身份驗證。它並不提供授權功能或者審計功能。

1.2. 概念

首次請求,三次通訊方

  • the Authentication Server
  • the Ticket Granting Server
  • the Service or host machine that you’re wanting access to.

 

圖 1‑1 角色

其他知識點

  • 每次通訊,訊息包含兩部分,一部分可解碼,一部分不可解碼
  • 服務端不會直接有KDC通訊
  • KDC儲存所有機器的賬戶名和密碼
  • KDC本身具有一個密碼

2.  3次通訊

 

  我們這裡已獲取伺服器中的一張表(資料)的服務以為,為一個http服務。

2.1. 你和驗證服務

  如果想要獲取http服務,你首先要向KDC表名你自己的身份。這個過程可以在你的程式啟動時進行。Kerberos可以通過kinit獲取。介紹自己通過未加密的資訊傳送至KDC獲取Ticket Granting Ticket (TGT)。

(1)資訊包含

  • 你的使用者名稱/ID
  • 你的IP地址
  • TGT的有效時間

  Authentication Server收到你的請求後,會去資料庫中驗證,你是否存在。注意,僅僅是驗證是否存在,不會驗證對錯。

  如果存在,Authentication Server會產生一個隨機的Session key(可以是一個64位的字串)。這個key用於你和Ticket Granting Server (TGS)之間通訊。

(2)回送資訊

  Authentication Server同樣會傳送兩部分資訊給你,一部分資訊為TGT,通過KDC自己的密碼進行加密,包含:

  • 你的name/ID
  • TGS的name/ID
  • 時間戳
  • 你的IP地址
  • TGT的生命週期
  • TGS session key

另外一部分通過你的密碼進行加密,包含的資訊有

  • TGS的name/ID
  • 時間戳
  • 生命週期
  • TGS session key

 

圖 2‑1 第一次通訊

  如果你的密碼是正確的,你就能解密第二部分資訊,獲取到TGS session key。如果,密碼不正確,無法解密,則認證失敗。第一部分資訊TGT,你是無法解密的,但需要展示快取起來。

2.2. 你和TGS

如果第一部分你已經成功,你已經擁有無法解密的TGT和一個TGS Session Key。

(1)    請求資訊

 a)  通過TGS Session Key加密的認證器部分:

  • 你的name/ID
  • 時間戳

b)       明文傳輸部分:

  • 請求的Http服務名(就是請求資訊)
  • HTTP Service的Ticket生命週期

c)        TGT部分

  Ticket Granting Server收到資訊後,首先檢查資料庫中是否包含有你請求的Http服務名。如果無,直接返回錯誤資訊。

  如果存在,則通過KDC的密碼解密TGT,這個時候。我們就能獲取到TGS Session key。然後,通過TGS Session key去解密你傳輸的第一部分認證器,獲取到你的使用者名稱和時間戳。

TGS再進行驗證:

  1. 對比TGT中的使用者名稱與認證器中的使用者名稱
  2. 比較時間戳(網上有說認證器中的時間錯和TGT中的時間錯,個人覺得應該是認證器中的時間戳和系統的時間戳),不能超過一定範圍
  3. 檢查是否過期
  4. 檢查IP地址是否一致
  5. 檢查認證器是否已在TGS快取中(避免應答攻擊)
  6. 可以在這部分新增許可權認證服務

  TGS隨機產生一個Http Service Session Key, 同時準備Http Service Ticket(ST)。

(2)    回答資訊

  a)        通過Http服務的密碼進行加密的資訊(ST):

  • 你的name/ID
  • Http服務name/ID
  • 你的IP地址
  • 時間戳
  • ST的生命週期
  • Http Service Session Key

  b)       通過TGS Session Key加密的資訊

  • Http服務name/ID
  • 時間戳
  • ST的生命週期
  • Http Service Session Key

  你收到資訊後,通過TGS Session Key解密,獲取到了Http Service Session Key,但是你無法解密ST。

 

圖 2‑2 第二次通訊

2.3. 你和Http服務

  在前面兩步成功後,以後每次獲取Http服務,在Ticket沒有過期,或者無更新的情況下,都可直接進行這一步。省略前面兩個步驟。

(1)    請求資訊

  a)        通過Http Service Session Key加密部分

  • 你的name/ID
  • 時間戳

  b)       ST

   Http服務端通過自己的密碼解壓ST(KDC是用Http服務的密碼加密的),這樣就能夠獲取到Http Service Session Key,解密第一部分。

服務端解密好ST後,進行檢查

  1. 對比ST中的使用者名稱(KDC給的)與認證器中的使用者名稱
  2. 比較時間戳(網上有說認證器中的時間錯和TGT中的時間錯,個人覺得應該是認證器中的時間戳和系統的時間戳),不能超過一定範圍
  3. 檢查是否過期
  4. 檢查IP地址是否一致
  5. 檢查認證器是否已在HTTP服務端的快取中(避免應答攻擊)

(2)    應答資訊

a)        通過Http Service Session Key加密的資訊

  • Http服務name/ID
  • 時間戳

 

圖 2‑3 第三次通訊

  你在通過快取的Http Service Session Key解密這部分資訊,然後驗證是否是你想要的伺服器傳送給你的資訊。完成你的伺服器的驗證。

至此,整個過程全部完成。

3.  實現

github地址:https://github.com/wukenaihe/KerberosService

 

  github上面的程式暫時還沒有詳細的說明。自己感覺設計的稍微有點亂。自己之所以要重新實現的原因就是現在MIT的kerberos、apache directory、Windows AD配置都相當麻煩,使用起來也非常麻煩。所以想從新設計一個簡單易用的,但是同時又考慮到靈活性(又不想依賴於spring)所以,總體感覺略亂。現在,加密通過AES方式,密碼儲存用檔案,序列化通過kryo.

  專案中使用後,準備再新增使用說明,和程式結構。如果有任何疑問,歡迎詢問。

3.1.  專案組成及功能

子專案名

功能

依賴

ks-parent

Pom型別,定義依賴與版本

 

ks-common

傳輸的bean,異常體系,基本工具類

ks-parent

ks-server

KDC服務端

ks-parent、ks-common

ks-client

KDC客戶端

ks-parent、ks-common

ks-tool

KDC工具類,服務端database檔案管理,客戶端密碼檔案管理。可以擴充套件資料庫

ks-parent、ks-common

ks-example

例子

 

3.2. Ks-common

  基礎的JavaBean,主要包含6次傳輸過程中的javabean,還有ServiceTicket與TicketGrantingTicket。

  Kerberos部分錯誤通過異常進行傳輸,因此涉及到的所有異常較多。在該系統中所有的異常均為runtime異常,避免強制catch。

  工具類,主要包含Kryo序列化工具(非執行緒安全)、安全工具類(AES、DES加密演算法)、時間比較類。

3.2.1.    基礎類(com.cgs.kerberos.bean)

這裡的類均為2章中,3次通訊過程中的資訊封裝。所有的類均是可序列化的,在該專案中通過Kryo進行序列化。

 

圖 4‑1通訊間的資訊封裝

除了第一次請求和最後一次應答,其他部分均包含能解析部分與不可解析部分。持有者不可能對不可解析部分修改,所以不可解析部分包含著進行驗證的資訊及用於解密的鑰匙。

TGT包含的是客戶端資訊,及一把鑰匙;主要使用者KDC驗證,請求者是否合法。ST包含客戶端資訊,及一把鑰匙;主要用於請求伺服器(非KDC),驗證客戶端。

1.2.2.    異常體系

 

圖 4‑2 異常體系

  異常體系主要由Kerberos的異常系列和加密演算法異常體系兩部分組成。

3.2.3.    工具類

  KryoSerializer將物件轉化為byte[]二進位制,將二進位制轉化為物件。

  Kryo在持久化速度和持久化後的空間上,都有無可比擬的速度。它的缺點:只能在java語言中使用、不能做相容性。考慮到,呼叫該kerberos的系統使用的持久化方式為kryo,我們這裡預設的也採用kryo持久化。Bug較多,不過在該系統使用到的功能中,均無bug。

  在該框架中,不需要用到物件之間的引用。同時,因為是通過網路傳輸的,所以不能進行註冊。(會把類的全限定麼全部持久化進去)。

  KryoSerializer據說是非執行緒安全的。

  SecurityUtil:通過DES或者AES進行加密與解密。DES通過64位密碼加密,所以如果字串少於8個,則後面加0填充,如果多餘則擷取前面8位。AES通過128位加密,如果字串少於16,則後面加0填充,多餘則擷取。

  在該專案中,使用AES進行加解密。

3.3. Ks-server

  KDC中心,主要包含Authentication Server、Ticket Granting Server。Authentication Server認證請求伺服器是否合法(A請求B,KDC驗證A的合法性),服務票據請求服務(Ticket Granting Server),授予服務請求票據(通過Ticket,B能確定A的合法性)。

 

圖 4‑3 KDC伺服器監聽服務

  監聽到Socket請求後,交由具體類進行處理。具體類由對應的物件生成器生成。通過物件生成器生成,可以方便的替換持久化方式、加密方式、資料儲存方式(該系統不依賴於Spring)。

 

圖 4‑4 生成器結構

  通過構建者模式,生成複雜的類結構。TGT處理類生成器與TGS處理類生成器,均包含資料庫處理器生成器與序列化生成器。資料庫處理類生成器現在只實現了檔案資料庫生成器、以後一定會新增資料庫資料庫生成器(將使用者名稱與密碼儲存至資料庫)。序列化生成器,目前只包含Kryo序列化生成器。

3.3.1.    Authentication Server

  BaseTgtProcessor類進行處理,服務端是無狀態的,每次請求過來都不需要儲存資訊。FirstResponse check(FirstRequest firstRequest) throws NoSuchUser方法檢查請求是否合法,並生成對應的應答資訊。

 

圖 4‑5 檢查合法性及應答資訊生成

3.3.2.    Ticket Granting Server

  服務票據授予服務,A請求B的服務。KDC給A一張票據,這樣B能夠確認A的合法性。

 

圖 4‑6檢查合法性及應答資訊生成

3.3.3.    ServletContextListener

  Servlet Context監聽器,在tomcat啟動的時候,也將KDC的服務啟動起來。在關閉的時候,一起關閉,不需要單獨成為一個應用程式。同時,能夠在web.xml裡面配置簡單的引數。

3.4. Ks-client

  KerberosClient介面中包含了,所有的基礎方法。詳見裡面註釋。客戶端需要儲存KDC返回的各類資訊,JavaBean結構如下所示:

 

圖 4‑7 客戶端javabean

 

圖 4‑8 客戶端架構

  KerberosFacade:門面模式,簡化使用方式。1、獲取請求服務時,如果ST或者TGT還不存在,會自動請求呼叫。2、其他客戶端請求時,檢查是否合法。3、請求服務返回時,檢查是否合法。

  KerberosFacadeMemory:將ST、TGT等資訊儲存在記憶體中。

  KerberosClient:主要負責和KDC互動

  KerberosClientServer:其他客戶端互動,檢查客戶端是否合法,生成應答資訊。

  FileClientDatabaseProcessor:以檔案形式,儲存客戶端的賬戶密碼。

  加密方式,KDC與客戶端必須一致。我們這裡預設使用AES加密,如果需要採用別的加密方式,需要重新實現。

 

4.  參考

http://www.roguelynn.com/words/explain-like-im-5-kerberos/

http://www.cnblogs.com/artech/archive/2011/01/24/kerberos.html