NTLM身份鉴别机制及在 T0Net系统中的应用
2011-01-12桂兵祥
桂兵祥
(武汉工业学院计算机与信息工程系,湖北武汉 430023)
NTLM是一个身份鉴别协议[1],由 NTLMSSP(NTLM Security Support Provider)支持,主要应用于不同的微软网络协议实现中。其早期应用于 DCE/RPC的安全鉴别与协商,其还作为一个单一签名机制整合于无处不在的微软系统中。其使用了基于挑战 -响应机制的鉴别方法,该机制中,客户端能在不发送用户密码给服务器的情况下就能实现用户的身份鉴别,其通常由协商 (negotiation)、挑战 (challenge)和鉴别 (authentication)三类消息组成。
1 NTLM身份鉴别机制基本原理
NTLM是一个身份鉴别机制,其基本原理如图1所示。
第一步:客户端首先创建并发送第一类消息(协商 negotiation)给服务器,该消息中主要包含服务器端所要求的客户端的特征列表。
第二步:服务器接收并分析该消息,然后创建第二类消息 (挑战 challenge)并发往客户端,以此与客户端建立协商,并对之提出挑战,其可能随意性地包含鉴别对象特征列表中的一些信息。
第三步:客户端创建第三类消息 (鉴别 authentication)对第二类挑战消息做出响应,以实现鉴别功能,该消息不用直接发送密码也能显示出客户端特定的身份信息。
图1 挑战响应机制原理示意图
对于服务器发来的挑战,客户端可以创建一个或多个响应消息,这些响应消息共分以下五类:①LM(LAN Manager)响应——大多数客户端发出此类响应,其也是最原始的响应类型;②NTLM响应——此类响应主要由基于 NT构架的客户端发出,包括 Windows 2000和 XP;③NTLMv2响应——这是一个新的响应类型,Windows NT Service Pack 4对此有所介绍。在激活的 NTLM version 2系统中,其代替了 NTLM响应;④LMv2响应——在 NTLM version 2系统中,其是 LM响应的替代者;⑤NTLM2会话响应—其用于无 NTLMv2鉴别情况下的 NTLM2会话安全协商过程中,此策略对 LM响应和NTLM响应的语义有所改变。
大多数客户端发出的是 LM响应类,这一策略早于 NTLM响应,安全性不如 NTLM,当新一代的客户端支持 NTLM时,其往往将此两类响应一并发送,以实现与不同合法的服务器间的兼容性,因此,在很多LM响应类型客户端、尽管其支持 NTLM响应,但安全缺陷依然存在。而NTLM响应是由新一代客户端发出,这一策略在安全性方面较 LM响应有很大的改进。
2 应用于Window系统的 NTLM实用技术—NTLMSSP和 SSPI
Windows系统提供了一个用户身份鉴别框架,就是著名的 SSPI(the Security Support Provider Interface),类似于微软的 GSS-API(Generic Security Service Application Program Interface),它提供了应用于网络协议上层、具有独立机制的身份鉴别方式。SSPI支持几个潜在的服务供应商,NTLMSSP(NTLM Security Support Provider)就是其中之一,它提供了NTLM鉴别机制,上面已有所提及。
SSPI提供了十分灵活的 API,用于处理非透明的、特殊提供者的鉴别令牌,前面提到的 NTLM的各类消息就是这样的令牌,其细节由 NTLMSSP处理。SSPI提供的 API对 NTLM的所有细节进行了精简,应用开发人员甚至不需要意识到正在应用 NTLM。这里仅简要地描述应用于 NTLM中的 SSPI鉴别握手过程 (如图2所示)。
图2 NTLM中的 SSPI鉴别握手过程
(1)客户端通过 SSPI的 Acquire Credentials Handle函数获得为用户设置的信用描述信息,然后调用SSPI的 Initialize Security Context函数以获得一个鉴别请求令牌,如前述中的第一类消息。最后发送此令牌给服务器端,Initialize Security Context函数返回值指明鉴别过程将要求多步操作才能完成。
(2)服务器端接收从客户端发来的令牌,以此作为输入,调用 SSPI的 Accept Security Context函数,由此在服务器端创建了本地安全上下文,描述客户端。然后产生一个鉴别响应令牌,如前述中的第二类消息,发往客户端。Accept Security Context函数的返回值指明有必要进一步从客户端获取信息,以完成鉴别过程。
(3)客户端接收由服务器端发来的响应令牌,以此做为输入,再次调用 Initialize Security Context函数,产生另一个鉴别请求令牌,如前述中的第三类消息,其返回值指明安全上下文已被成功地初始化,然后将此鉴别请求令牌发往服务器端。
(4)服务器端接收由客户端发来的令牌,以此作为输入,再次调用 Accept Security Context函数,其返回值指明上下文已被成功地接收,不再产生新的令牌,鉴别过程到此完成了。
3 NTLM身份鉴别机制在 T0Net系统实际开发中的应用
3.1 T0Net系统概述
T0Net系统主要功能是为不同的局域网之间的通信提供安全、透明的通讯平台。目前,局域网应用已十分普遍,尤其是局域网内的通信、远程控制与交互式协作非常方便。但是,随着经济的全球化,企业的地域界限早已被打破,集中式的办公方式已为分布式的办公方式所取代,这就要求在不同的局域网之间能进行安全、便捷的通信,然而,几乎所有的局域网为了安全都装有防火墙,这给局域网和局域网之间 (通过 INTERNET)通信的便捷性、远程控制与交互式协作造成很大的障碍[2]。T0Net网络系统能穿透防火墙、为企业与企业之间、企业与客户之间建立起安全、便捷、交互式的通讯平台,实现了应用级的共享。
T0Net系统能将分布式的局域网通过 INTER-NET连接成一个大的虚拟局域网,实现安全、透明的访问。与任何系统一样,用户在登录使用该服务之前,都有一个身份认证与鉴别过程。通常的方法是先为每个用户建立一个用户名和密码,然后,用户使用该用户名和密码登录,服务器通过比较鉴别以确定该用户是否合法。该方法中,用户名和密码无论是以明文还是加密传输,都不能提供足够的安全性。而作为基于挑战 -响应的新型用户鉴别机制,NTLM技术在身份认证与鉴别方面,具有更高的安全性。在 T0Net系统就使用了这种机制。
3.2 NTLM在 T0Net系统中的应用
根据面向对象程序设计思想[3]:首先创建了一个基类 class CXNTLMPdu;然后在此基础上派生三个消息类:class CXNTLMNegotiationPdu;class CXNTLMChallengePdu class和CXNTLMAuthenticationP-du;最后,因为 NT LM各类消息是通过 http协议来传输的,故还创建了一个类 class CXNTLMOverHttpMgr。具体NTLM类图创建及继承关系如图3所示。
图3 NTLM类图及继承关系示意图
部分代码框架如下。
基类 class CXNTLMPdu:
class CXNTLMPdu
{
………
public:
BOOL Encode (CXCharStr&strBase64Serialized);
static CXNTLMPdu* Decode(CXCharStr&str-Base64Serialized);
………
public:
static void NTLMS wap(void* pData,int size);
static void SerializeWStrTo(CXByteStream&os,CXWCharStr&wstr);
static void SerializeWStrFrom(LPBYTE lpBuf,WORD wByteLength,
CXWCharStr&wstr);
static void SerializeStrFrom (LPBYTE lpBuf,WORD wByteLength,
CXCharStr&str);
static void Serialize Blob From(LPBYTE lpBuf,WORD wByte Length,
CXBlob&blob);
………
};
三个派生消息类:
1)协商 (negotiation)-class CXNTLMNegotiationPdu;
classCXNTLMNegotiationPdu:publicCXNTLMPdu
{
………
public:
virtual int GetPduType(){return XNTLM_NEGOT IAT ION_PDU;}
virtual DWORD Get Serial Length();
virtual DWORD Serialize To(LPBYTE lp Buffer,DWORD dw Length);
virtual DWORD Serialize From(LPBYTE lp Buffer,DWORD dw Length);
………
};
2)挑战 (challenge)-class CXNTLMChallengeP-du;
class CXNTLMChallengePdu:public CXNTLMP-du
{
………
public:
virtual int GetPduType(){return XNTLM_CHALLENGE_PDU;}
virtualDWORD Get SerialLength();
virtual DWORD SerializeTo(LPBYTE lpBuffer,DWORD dw Length);
virtualDWORD SerializeFrom(LPBYTE lpBuffer,DWORD dw Length);
………
BYTE m_abChallenge[8];
BYTE m_abContext[8];
CXPtr Listm_aTarget Info List;
};
3)鉴别 (authentication)-class CXNTLM Authentication Pdu;
class CXNTLM Authentication Pdu:public CXNTLMPdu
{
………
public:
virtual int GetPduType(){return XNTLM_AUTHENTICAT ION_PDU;}
virtualDWORD GetSeria lLength();
virtual DWORD SerializeTo(LPBYTE lpBuffer,DWORD dwLength);
virtualDWORD SerializeFrom(LPBYTE lpBuffer,DWORD dwLength);
public:
//pChalenge points to 8-byte challenge from NTLM type-2 message
//pHash points to a 24-byte buffer
static BOOL GenerateLMHash(LPCSTR lpszPassword,
LPBYTE pChallenge,LPBYTE pHash);
static BOOL GenerateNTLMHash(LPCSTR lpsz-Pass word,
LPBYTE pChallenge,LPBYTE pHash);
static BOOL GenerateHash(LPBYTE ab3Keys,
LPBYTE pChallenge,LPBYTE pHash);
static void SetupDESKey(unsigned char* key_56,
des_key_schedule&ks);
public:
CXBlob&RefLMResponse(){returnm_blobLMResponse;}
CXBlob&RefNTLMResponse(){return m_blobNTLMResponse;}
………
CXBlob m_blobLMResponse;
CXBlob m_blobNTLMResponse;
………
};
最后,NTLM各类消息是通过 http协议来传输的,故还创建了一个类 class CXNTLMOverHttpMgr;
class CXNTLMOverHttpMgr
{
public:
CXNTLMOverHttpMgr();
virtual~CXNTLMOverHttpMgr();
………
public:
void Initiate();
BOOL GetNTLM Http Request(CXCharStr&strRequest);
BOOL Process NTLMHttpResponse (LPCSTR lpszResponse);
void Reset();
public:
virtual void Get Authentication Info(
………
CXBlobm_blob Challenge;
CXCharStrm_str Target Name;
};
4 结束语
目前,C/S模式中,大多数客户端发出的是 LM响应类,这一策略早于 NTLM响应,安全性不如 NTLM,当新一代的客户端支持 NTLM时,其往往将此两类响应一并发送,以实现与不同的合法服务器间的兼容性,因此,在很多 LM响应类型客户端、尽管其支持NTLM响应,但安全缺陷依然存在。而NTLM响应是由新一代客户端发出,这一策略在安全性方面较LM响应有大的改进。然而,众所周知,网络安全具有相对性,NT LM也并非无懈可击,当 NTLM响应连带LM响应一并发出时,此算法上的脆弱性还是可能被黑客所利用,以获得NTLM响应所用的相关密码。尽管如此,NT LM身份认真与鉴别机制仍然具有较高的安全性,能满足绝大多数用户的的需求。T0Net系统现已投入使用,取得了较好的实用效果。
[1] Eric Glass.The NTLM Authentication Protocol[EB/OL].[2009-12-15].http://davenport.sourceforge.net/ntlm.html.
[2] 袁津生.计算机网络安全基础 [M].北京:人民邮电出版社,2008.
[3] 张海潘.面向对象的程序设计 [M].北京:清华大学出版社,2008.