VPN身份認證技術
對于一些使用PPP協議通信的二層VPN方案,如PPTP VPN和L2TP VPN,是直接采用數據鏈路層PPP協議支持的PAP(Password Authentication Protocol,密碼認證協議)或CHAP(Challenge Handshake Authentication Protocol,質詢握手認證協議)進行用戶身份認證的。但必須確保PPP鏈路兩端的接口上啟用了相同的PPP認證方式,并且相關功能配置正確。而在一些三層VPN方案中,要使用密鑰進行認證,這就涉及一些認證密鑰算法,如MD5、SHA、SM3等。
1. PAP協議報文格式及身份認證原理
以下內容是針對PPP協議進行介紹的,但同時適用于PPP協議的擴展協議,如PPTP和L2TP協議。
(1)PAP報文格式
PAP協議是PPP協議簇中的一個,與PPP一樣同位于數據鏈路層,但在PPP協議之上,其幀也要受到PPP協議封裝。PPP協議數據幀格式如圖1所示,如果封裝的是PAP報文,則其中的“協議”字段值為0x C023。

圖1 PPP數據幀格式
PAP協議報文格式如圖2所示,各字段說明如下:

圖2 PAP協議報文格式
Code:報文代碼,8字節,用于識別PAP報文類型,1為Authenticate-Request (認證請求),2為Authenticate-ACK(認證確認),3為Authenticate-NAK(認證否認)。
Identifier:報文標識符,8字節,類似于報文序列號,同一組認證進程下的請求報文和應答報文標識符一致。
Length:長度,16字節,以字節為單位標識整個PAP報文(包括本字段)的長度。
Data:數據,長度可變,具體內容會因PAP報文類型的不同而不同,如果是ACK報文,該字段長度為0;NAK報文中該字段會說明認證失敗的原因;Request報文中該字段為用于進行身份認證的用戶憑據信息。
(2)PAP協議身份認證原理
PAP協議的身份認證過程非常簡單,是一個二次握手機制,整個認證過程僅需兩個步驟:被認證方(PPP客戶端)發送認證請求→認證方(PPP服務器)給出認證結果。但是它是一種以明文方式在線路上傳輸認證用戶名和密碼,所以安全性不高。
PAP認證可以在一方進行,即僅由一方對另一方的身份進行認證,通常是是由PPP服務器對PPP客戶端進行認證;也可以進行雙向身份認證,也就是既要PPP服務器對PPP客戶端進行認證,PPP客戶端也需要對PPP服務器進行認證,以確保用于認證的PPP服務器是合法的。如果是雙向認證,則要求被認證的雙方都要通過對方的認證程序,否則無法在雙方之間建立通信鏈路。
下面以單向認證為例介紹PAP認證過程,如圖3所示。但要注意的是,PAP認證是由被認證方(PPP客戶端)首先發起的。

圖3 PAP身份認證的兩次握手
1)發起PPP連接的客戶端(被認證方)首先以明文方式向PPP服務器端發送一個認證請求(Authenticate-Request)幀,其中就包括用于身份認證的用戶名和密碼;
2)PPP服務器端(認證方)在收到客戶端發來的認證請求幀后,先查看PPP服務器本地配置的用戶賬戶數據庫,看是否有客戶端提供的用戶名(這個用戶賬戶數據庫存必須先在PPP服務器端配置好)。如果有,且對應的用戶賬戶密碼也一致,則表明客戶端具有合法的用戶賬戶信息,向PPP客戶端返回一個認證確認(Authenticate-ACK)幀,表示認證成功,則該用戶可以與PPP服務器端建立PPP連接。
如果在本地數據庫中找不到與客戶端發來的用戶名一致的用戶賬戶,或者雖然有相同名稱的用戶賬戶,但密碼不一致,則會認證失敗,返回一個認證拒絕(Authenticate-NAK)幀,客戶端也不能與PAP服務器端建立PPP連接。
如果第一次認證失敗,并不會馬上將鏈路關閉,而是會在PAP客戶端提示可以嘗試以新的用戶賬戶信息進行再次認證,只有當認證不通過的次數達到一定值(缺省為4)時才會關閉鏈路,以防止因誤傳、網絡干擾等造成不必要的LCP重新協商過程。
以上介紹的是PAP單向認證過程,僅兩步(一問一答形式),很簡單。PAP雙向認證過程與單向認證過程類似,只不過此時PPP鏈路的兩端是同時具有客戶端和服務器雙重角色,任何一端都向對方發送認證請求,同時對對方發來的認證請求進行認證。
2. CHAP協議報文格式及身份認證原理
以下內容是針對PPP協議進行介紹的,但同時適用于PPP協議的擴展協議,如PPTP和L2TP協議。
(1)CHAP報文格式
CHAP協議也是PPP協議簇中的一個,是用于進行身份認證的,也與PPP協議一樣位于數據鏈路層,但在PPP協議之上,其報文也要受到PPP協議封裝,對應的協議號為0x C223。CHAP報文格式與PAP協議報文格式一樣,參見圖2。但各字段的含義有所區別,具體說明如下。
Code:報文代碼,8字節,用于識別PAP報文類型,1為Challenge(質詢),2為Response(響應),3為Success(認證成功),4為Failure(認證失敗)。
Identifier:報文標識符,8字節,類似于報文序列號,同一組認證進程下的各類報文標識符一致。
Length:長度,16字節,以字節為單位標識整個CHAP報文(包括本字段)的長度。
Data:數據,長度可變,具體內容會因CHAP報文類型的不同而不同,Success和Failure報文中該字段身份認證成功或失敗的的一段文本說明信息;Challenge報文中該字段為主認證方發送被認證方的隨機MD5摘要消息;Response報文中該字段為被認證方發給主認證方的一個經過MD5加密的Hash(哈希)值。
(2)CHAP身份認證原理
CHAP協議的身份認證過程相對前面介紹的PAP認證來說更為復雜,采用的是三次握手機制(而不是PAP中的兩次握手機制),整個認證過程要經過三個主要步驟:認證方(PPP服務器)要求被認證方(PPP客戶端)提供認證信息→被認證方提供認證信息→認證方給出認證結果。
其次,CHAP身份認證方式相對PAP認證方式來說更加安全,因為在認證過程中,用于認證的密碼不是直接以明文方式在網絡上傳輸的(用戶名仍是以明文方式傳輸),而是封裝在MD5加密摘要信息中,更加安全。CHAP認證的具體步驟還與認證方是否配置了用戶名有關,推薦使用驗證方配置用戶名的方式,這樣被認證方也可以對認證方的身份進行確認,相當于PPP客戶端對PPP服務器的身份也可以進行認證。
同PAP認證一樣,CHAP認證也可以是單向或者雙向的。如果是雙向認證,則要求通信雙方均要通過對對方請求的認證,否則無法在雙方建立PPP鏈路。在此,我們仍以單向認證為例介紹CHAP認證流程。具體如圖4所示,但要注意,CHAP身份認證首先是由PPP服務器端主動發起質詢的。

圖4 CHAP身份認證的三次握手
1)當PPP客戶端要與PPP服務器建立連接,并且配置采用CPAP身份認證方式時, PPP服務器(認證方)會首先向PPP客戶(被認證方)端發送一個隨機報文(如果認證方配置了用戶名,則還隨同發送認證方的用戶名)進行“質詢”(Challenge,也稱“挑戰”),詢問客戶端用于身份認證的賬戶信息。同時這個發送的隨機報文會保存在緩存中。
2)PPP客戶端在收到服務器端發來的質詢消息后,如果隨機報文中包括了PPP服務器的用戶名,則先看本地是否配置了PPP服務器的賬戶信息對PPP的身份進行認證(如果收到的隨機報文中不包括PPP服務器的用戶賬戶信息,則不需要對PPP服務器身份進行認證),認證通過后再把所收到的隨機質詢報文與PPP客戶端配置的賬戶密碼(相當于MD5算法中所說的“共享密鑰”)采用MD5算法進行加密,將生成的MD5摘要密文和自己的用戶名發回PPP服務器進行響應(Response)。
3)PPP服務器端在收到來自客戶端的響應后,首先直接利用來自PPP客戶端的明文用戶賬戶名在本地數據庫中進行查找,如果找不到該賬戶,則直接認證為認證失敗;如果在本地數據庫中有該用戶賬戶就可以得到本地配置的該賬戶的密碼,然后再利用所查到的該賬戶密碼與原來發送給客戶端,并且在緩存中保存的隨機質詢報文進行同樣的MD5哈希計算,看最終的結果與來自PPP客戶端的MD5哈希報文進行比較。
如果兩個MD5哈希報文完全一致(如果本地配置的該賬戶密碼與在PPP客戶端配置的一樣,則肯定一致,因為此時進行哈希計算時的MD5報文和密碼都是一樣的),則認為PPP客戶端具有合法的用戶賬戶信息,認證通過,向PPP客戶端發送認證成功(Sucess)幀,成功進行PPP連接;否則表示認證失敗,向PPP客戶端發送認證失敗(Failure)幀,不能建立PPP連接。
與PAP一樣,第一次認證失敗后,也不會馬上關閉鏈路,而是再次向客戶端提示輸入新的用戶名和密碼進行再次認證,直到規定的最高嘗試次數。
3. 身份認證算法
在一些三層VPN解決方案中,還涉及到許多用于生成身份認證密鑰的算法,如在IPSec VPN中使用的AH和ESP安全協議就支持多種認證算法——MD5、SHA1、SHA2(包括sha2-256、sha2-384、sha2-512)、SM3、 AES-XCBC-MAC-96,這些其實都是屬于哈希,摘要,或者雜湊算法。
在這些算法中都需要用到一些特定的函數運算方法,這些函數的名稱也對應有多種,如“哈希(Hash)函數”,或“消息摘要函數”“雜湊函數”“單向散列函數”,這些函數運算的基本設計思想是將輸入的任意長度消息,通過運算后得到一個固定長度的輸出值。這個輸出值也就對應稱之為“哈希值”,或“消息摘要”“雜湊值”“散列值”等。這個消息摘要會隨同消息一起發送到對方,對方再用相同的摘要算法對所接收的消息數據進行運算,看結果是否與隨同消息一起發送、在源端得出的摘要相同,如果相同,則表示消息數據在傳輸過程中沒有被篡改,可以放心使用;不同,則表示消息數據在傳輸過程中被非法篡改,不可用。
哈希函數(或雜湊函數)可以按其是否有密鑰參與運算分為“不帶密鑰的哈希函數”和“帶密鑰的哈希函數”。不帶密鑰的哈希函數在運算過程中沒有密鑰參與,只有原始消息輸入。這類哈希函數不具有身份認證功能,僅提供數據完整性檢驗,稱之為MDC(篡改檢測碼)。而帶密鑰的哈希函數在消息的運算過程中是有密鑰參與的,即哈希值(或雜湊值)同時與密鑰和原始消息的輸入有關,只有擁有密鑰的人才能計算出相就的哈希值。所以帶密鑰的哈希函數不僅能檢測數據完整性,還能提供身份認證功能,被稱之為MAC (消息認證碼)。現在通常是采用帶密鑰的哈希函數。