解析XMPP協(xié)議分析與應用
3.1 簡(jiǎn)單認證和安全層協(xié)商機制
簡(jiǎn)單認證和安全層(Simple Authentication and Security Layer,SASL)可以為基于連接的協(xié)議加入認證機制,提供KERBEROS_V4、PLAIN和DIGEST-MD5等多種認證方法。每種認證機制包含認證機制名、認證過(guò)程初始化命令、認證控制命令、特定8位碼和解釋器等信息。
在認證過(guò)程中,認證服務(wù)器完成認證、授權標識傳送、簡(jiǎn)單認證和安全層協(xié)商3個(gè)方面的工作。在XMPP中,SASL處理步驟如下(C:客戶(hù)端,S:SASL認證服務(wù)器):
?。?)C、S之間建立連接。(2)S向C提供認證機制列表。(3)C在認證機制列表中選擇一種認證機制。(4)S向C詢(xún)問(wèn)授權信息。(5)C向S提交授權信息。(6)S向C返回認證成功或失敗信息。
3.2 回撥認證
在通信過(guò)程中,2個(gè)XMPP服務(wù)器之間經(jīng)常需要通信,為避免利用服務(wù)器欺騙方式進(jìn)行信息偽造,XMPP 采用了回撥認證機制?;負苷J證依靠DNS技術(shù)完成,利用回撥認證機制,一個(gè)服務(wù)器可以確認與自己建立連接的服務(wù)器是否經(jīng)過(guò)合法授權,回撥認證過(guò)程為:(1)源服務(wù)器和接收服務(wù)器建立連接,并向接收服務(wù)器請求認證。接收服務(wù)器回應,并分配認證會(huì )話(huà)ID。(2)源服務(wù)器向接收服務(wù)器發(fā)送認證密鑰。(3)接收服務(wù)器與認證服務(wù)器建立連接。認證服務(wù)器同時(shí)為該認證會(huì )話(huà)分配一個(gè)驗證會(huì )話(huà)ID。(4)接收服務(wù)器把源服務(wù)器提交來(lái)的密鑰和驗證會(huì )話(huà)ID 發(fā)送給認證服務(wù)器,請求驗證。(5)認證服務(wù)器驗證密鑰,并給接收服務(wù)器返回認證結果。(6)接收服務(wù)器給源服務(wù)器返回認證結果。
3.3 加 密
雖然SASL提供了先進(jìn)的認證機制,通信雙方必須經(jīng)過(guò)特定的授權認證才能進(jìn)行正常通信,但是登錄信息一般都是密碼和用戶(hù)名等重要信息,它們大多采用明文方式傳送,因此很容易被竊聽(tīng)。為解決該問(wèn)題,XMPP采用基于傳輸層安全協(xié)議的“STARTTLS”擴展來(lái)為通信雙方提供機密性和數據完整性服務(wù)。TLS 協(xié)議包括兩個(gè)協(xié)議組DD TLS 記錄協(xié)議和 TLS 握手協(xié)議DD每組具有很多不同格式的信息。TLS 記錄協(xié)議是一種分層協(xié)議。每一層中的信息可能包含長(cháng)度、描述和內容等字段。記錄協(xié)議支持信息傳輸、將數據分段到可處理塊、壓縮數據、應用 MAC 、加密以及傳輸結果等。對接收到的數據進(jìn)行解密、校驗、解壓縮、重組等,然后將它們傳送到高層客戶(hù)機。TLS 連接狀態(tài)指的是TLS 記錄協(xié)議的操作環(huán)境。它規定了壓縮算法、加密算法和 MAC 算法。TLS 記錄層從高層接收任意大小無(wú)空塊的連續數據。密鑰計算:記錄協(xié)議通過(guò)算法從握手協(xié)議提供的安全參數中產(chǎn)生密鑰、 IV 和 MAC 密鑰。TLS 握手協(xié)議由三個(gè)子協(xié)議組構成,允許對等雙方在記錄層的安全參數上達成一致、自我認證、例示協(xié)商安全參數、互相報告出錯條件。
TLS協(xié)議框架主要有2個(gè)層次的協(xié)議:TLS握手協(xié)議和TLS記錄協(xié)議。TLS握手協(xié)議用來(lái)讓服務(wù)器與客戶(hù)在傳輸應用層數據之前交換TLS協(xié)議版本信息、協(xié)商加密算法、進(jìn)行(相互)身份認證并交換密鑰。TLS記錄協(xié)議用來(lái)將應用層提供的信息進(jìn)行分組、壓縮、數據完整性檢查和加密。數據完整性檢查通過(guò)比較傳輸前后使用安全散列函數(如SHA和MD5 等)計算出來(lái)的數據的MAC值是否一致來(lái)完成。數據加密采用對稱(chēng)密碼算法(如R4和DES等)。對數據進(jìn)行完整性檢查和加密的密鑰由TLS握手協(xié)議來(lái)協(xié)商。
XMPP中采用的STARTTLS擴展處理流程如下(C:客戶(hù)端,S:TLS服務(wù)器):
?。?)C、S之間建立XML流會(huì )話(huà)連接。
?。?)S 向C 發(fā)送STARTTLS擴展服務(wù)需求及支持的其他認證機制列表,代碼實(shí)例如下:
stream:features>
starttls xmlns=′urn:ietf:params:xml:ns:xmpp-tls′>
required/>
/starttls>
mechanisms xmlns=′urn:ietf:params:xml:ns:xmppsasl′>
mechanism>DIGEST-MD5/mechanism>
mechanism>PLAIN/mechanism>
/mechanisms>
/stream:features>
?。?)C發(fā)送STARTTLS命令給S。
?。?)C、S中TLS握手協(xié)議開(kāi)始協(xié)商相關(guān)加密算法及密鑰。
?。?)若TLS握手協(xié)議協(xié)商成功,則關(guān)閉當前XML流會(huì )話(huà),C發(fā)起一個(gè)新的XML流會(huì )話(huà),所有傳送的信息均被TLS記錄協(xié)議加密。TLS握手協(xié)議協(xié)商不成功則發(fā)出警告信息。
?。?)S向C回復新XML流會(huì )話(huà)。
4 客戶(hù)端程序設計中的關(guān)鍵問(wèn)題
由于網(wǎng)絡(luò )中已存在大量的XMPP服務(wù)器,在一般的應用開(kāi)發(fā)中,只要設計自定功能的客戶(hù)端程序即可,并可以選用Smack庫來(lái)加速開(kāi)發(fā)。
?。?)創(chuàng )建一個(gè)XMPP連接。因為XMPP使用TCP協(xié)議,所以首先必須創(chuàng )建一個(gè)網(wǎng)絡(luò )連接,XMPPConnection就是Smack庫用來(lái)創(chuàng )建與XMPP服務(wù)器連接的類(lèi),創(chuàng )建一個(gè)XMPP連接的代碼如下:
XMPPConnection connection=new XMPPConnection(″jab-
ber.org″);
如要創(chuàng )建加密連接,可以使用SSLXMPPConnection類(lèi):
XMPPConnection connection=new SSLXMPPConnection(″jabber.org″);
?。?)登錄。TCP連接創(chuàng )建后,需要使用用戶(hù)名和密碼登錄到XMPP服務(wù)器,登錄程序可以使用XMPPConnection.login(String username,String password)方法。登錄后就可以和其他人聊天。
connection.login(″yb″,″password″);//connection為已創(chuàng )建的XMPP連接,下同
connection.createChat(″yb@sdpt.com″)。sendMessage
?。?Prime;Hello!″);
?。?)操作名冊。每個(gè)用戶(hù)都包括:一個(gè)XMPP地址(如mailto:%E2%80%9Cyb@sdpt.com”)、名稱(chēng)或昵稱(chēng)(如″yb″),及其所屬列表(如好友、同事等)。名冊能夠跟蹤好友或某用戶(hù)組是否在線(xiàn)及其狀態(tài)信息,登錄后,可以使用Roster類(lèi)來(lái)取得好友或某用戶(hù)組的狀態(tài),代碼如下:
Roster roster=con.getRoster( );
for (Iterator i=roster.getEntries( );i.hasNext( ); ) {
System.out.println(i.next( ));}
名冊信息通常是隨時(shí)變化的,可能需要增加或刪除。要監聽(tīng)名單及其在線(xiàn)狀態(tài)的改變,可以使用RosterListener。
?。?)發(fā)送和接收消息。發(fā)送接收消息可以使用Chat和GroupChat類(lèi)。下面介紹如何使用Chat發(fā)送文本消息,GroupChat的使用方法類(lèi)似。
Chat newChat=connection.createChat(″yb@sdpt.com″);//創(chuàng )建新Chat
newChat.sendMessage(″Hello!″);//發(fā)送消息″Hello!″
利用Chat.sendMessage( )方法可以方便地創(chuàng )建一個(gè)消息對象,它的參數就是消息內容,執行后消息會(huì )發(fā)送出去。
Chat newChat=connection.createChat(″yb@sdpt.com″);
newMessage.setBody(″Hi, I′m waiting for you.″);
while (true) {
Message message=newChat.nextMessage( );//等待對方發(fā)送消息
newChat.sendMessage(message.getBody());//把對方
}//發(fā)送來(lái)的消息發(fā)回去
?。?)修改狀態(tài)。要修改狀態(tài)可以用presence.Type.UNAV-ILABLE作為參數創(chuàng )建一個(gè)presence,狀態(tài)將改變?yōu)椴辉诰€(xiàn)狀態(tài)。
Presence presence=new Presence(Presence.Type.UNAVAILABLE);
presence.setStatus(″Gone skating″);
5 結束語(yǔ)
目前,全球有20萬(wàn)個(gè)即時(shí)通信平臺支持XMPP,有1 000萬(wàn)人在使用。簡(jiǎn)單的接口、開(kāi)放的協(xié)議、互聯(lián)的架構、權威的標準再加上堅實(shí)的用戶(hù)基礎是XMPP的優(yōu)勢。
評論