《电子技术应用》
您所在的位置:首页 > 通信与网络 > 设计应用 > XMPP协议分析与应用探讨
XMPP协议分析与应用探讨
摘要: 分析了XMPP协议的地址规范和数据结构,讨论了XMPP协议的工作过程和安全机制,给出了XMPP客户端程序设计中要考虑的关键问题。
关键词: XMPP协议
Abstract:
Key words :
</a>摘  要: 分析了XMPP协议" title="XMPP协议">XMPP协议" title="XMPP协议">XMPP协议" title="XMPP协议">XMPP协议的地址规范和数据结构,讨论了XMPP协议的工作过程和安全机制,给出了XMPP客户端程序设计中要考虑的关键问题。
关键词: XMPP  JID  XML流  认证  加密

  可扩展消息处理现场协议(eXtensible Messaging and Presence Protocol,XMPP)是一种基于可扩展标记语言(eXtensible Markup Language,XML)的近端串流式即时通信协议。它将现场和上下文敏感信息标记嵌入到XML结构化数据中,使得人与人之间、应用系统之间以及人与应用系统之间能即时相互通信。XMPP协议已被批准为互联网即时通信协议标准。
1  XMPP的地址和数据结构
1.1 实体地址
  XMPP整体框架如图1所示。图中,XMPP框架的各类实体(如XMPP客户、服务器和网关等)的地址称为甲吧地址(Jabber Identifier,JID)。JID惟一确定进行即时消息和在线状态信息通信的独立对象或实体,并可兼容其他即时通信系统(如MSN等)相应的实体标识及其在线状态信息。其语法规则为:[节点″@″] 域名[″/″资源],其中各个域的长度不能超过1 023 字节,总长度最大为3 071字节。

  域名指定了实体连接的XMPP服务器。每个可用XMPP服务器都拥有一个完整域名,域名可在域名系统(DNS)中查找;节点可表示某用户、一类应用或某项服务,所有节点都对应一个精确的域名;资源用来识别属于用户的特殊对象(如设备或位置),允许一个用户同时以多个资源与同一XMPP服务器连接,如yb@sdpt.com/labyb@sdpt.com/chat
1.2 XMPP的数据结构
  由于XMPP是基于XML的协议,因此用户可根据自己的需要定义标记,表述几乎任何一种结构化数据,并可方便地创建定制的应用或增加功能。
1.2.1 三个顶级XML元素
  XMPP定义的3个关键顶级XML元素为<message/>、<presence/>和<iq/>(info/query),每个元素都可以通过属性和名字空间包含大量数据,其属性和名字空间都是XMPP的组成部分。
<message/>元素用来包含2个XMPP实体间互相发送的消息内容;<presence/>元素表示实体可用性信息,可用性信息有“可用”和“不可用”2种;<iq/>元素用来构建2个实体间的会话,并且允许实体间来回传送XML格式的请求和响应以便取得或设置公共的用户信息,如名字等。
  即时通信中名字冲突问题使用XML的命名空间特性来解决。XML命名空间定义了一种将XML中使用的元素和属性与统一资源定位符(Uniform Resource Locator,URL)引用联系起来对元素和属性进行定义的方法。
1.2.2 XMPP的数据结构
  从结构上看,XMPP有3种数据:XML流、流认证和XML节。XML流是实体交换XML元素的容器,以<stream>开始,以</stream>结束,是通信双方采用异步方式进行数据传输的标准方法,在整个XMPP通信过程中处于最外层;XML节是实体通过XML流传输的结构化信息单元,在XML流中以深度为1的子标记开头,并以深度为1的子标记结束,这些标记为<message/>、<presence/>和<iq/>。XML节也可通过包含其他子元素来传送结构化信息,是实际需要交换的信息所在地;流认证是在XML流中有关协商传输层安全协议、简单认证与安全层协议和服务器回拨认证协议完成通信认证、加密等目的的数据交互,是XMPP安全机制的重要组成部分。
  XMPP为XML流扮演通用“传输层”的角色。XML流中包含传输的认证信息和现场消息,XMPP能使数据高效路由至最合适的请求源,并最大限度地简化客户机上的实现,使跨应用实时交流信息成为可能。
2  工作过程
  (1)节点(如yb、pt)向本地服务器连接。
  ①XMPP用户通过开启一个从客户端到服务器端的XML流,来申请一个在服务器上的Socket连接。
SEND: <stream:stream
     to=′sdpt.com′
     xmlns=′jabber:client′
     xmlns:stream=′http://etherx.jabber.org/streams′>
  ②服务器通过开启一个从服务器到客户端的XML流进行回复。
RECV: <stream:stream
     from=′sdpt.com′
     id=′180763465′
     xmlns=′jabber:client′
     xmlns:stream=′http://etherx.jabber.org/streams′>
  (2)节点向本地服务器申请登录。
  ①用户询问登录服务器时需提供的信息。
SEND: <iq id=′2′ type=′get′>
     <query xmlns=′jabber:iq:auth′>
        <username>yb</username>
     </query>
     </iq>
  ②服务器回应用户,告知用户登录所需要的信息。
  ③用户提供所需的信息。
  ④服务器响应一个空的类型为“result”的iq元素,表明登录成功。
  RECV:<iq id=′3′ type=′result′/>
  ⑤yb用户发送当前状态给服务器,表明其在线。
SEND: <presence>
  <status>Online</status>
     </presence>
  (3)用户获得花名册,好友增加一个联系人(如yb获知朋友sd在线)。
  (4)用户间发送消息(如yb向sd发送消息)。
  用户发送一条消息:
  SEND: <message to′sd@jabber.org′>
        <body>Where are you?</body>
     </message>
  服务器会根据XMPP用户的会话信息加上一个源地址,这样接收者收到消息时,消息中已经包含了源地址。
  (5)XMPP服务器根据目标JID中的域名查找、连接到目标服务器并进行认证(如sdpt.com使用DNS查找jabber.org,连接到jabber.org服务器上并进行认证)。
  (6)XMPP服务器jabber.org证实sd连接到该服务器上,yb被授权与sd进行通信。
  (7)数据在yb与sd间流动。
  (8)用户退出,退出时只需要关闭<stream>。
3  安全机制
3.1 简单认证和安全层协商机制
  简单认证和安全层(Simple Authentication and Security Layer,SASL)可以为基于连接的协议加入认证机制,提供KERBEROS_V4、PLAIN和DIGEST-MD5等多种认证方法。每种认证机制包含认证机制名、认证过程初始化命令、认证控制命令、特定8位码和解释器等信息。
  在认证过程中,认证服务器完成认证、授权标识传送、简单认证和安全层协商3个方面的工作。在XMPP中,SASL处理步骤如下(C:客户端,S:SASL认证服务器):
  (1)C、S之间建立连接。(2)S向C提供认证机制列表。(3)C在认证机制列表中选择一种认证机制。(4)S向C询问授权信息。(5)C向S提交授权信息。(6)S向C返回认证成功或失败信息。
3.2 回拨认证
  在通信过程中,2个XMPP服务器之间经常需要通信,为避免利用服务器欺骗方式进行信息伪造,XMPP 采用了回拨认证机制。回拨认证依靠DNS技术完成,利用回拨认证机制,一个服务器可以确认与自己建立连接的服务器是否经过合法授权,回拨认证过程为:(1)源服务器和接收服务器建立连接,并向接收服务器请求认证。接收服务器回应,并分配认证会话ID。(2)源服务器向接收服务器发送认证密钥。(3)接收服务器与认证服务器建立连接。认证服务器同时为该认证会话分配一个验证会话ID。(4)接收服务器把源服务器提交来的密钥和验证会话ID 发送给认证服务器,请求验证。(5)认证服务器验证密钥,并给接收服务器返回认证结果。(6)接收服务器给源服务器返回认证结果。
3.3 加  密
  虽然SASL提供了先进的认证机制,通信双方必须经过特定的授权认证才能进行正常通信,但是登录信息一般都是密码和用户名等重要信息,它们大多采用明文方式传送,因此很容易被窃听。为解决该问题,XMPP采用基于传输层安全协议(Transport Layer Security,TLS)的“STARTTLS”扩展来为通信双方提供机密性和数据完整性服务。TLS协议基于对称密钥算法和公钥加密算法,能为各类客户/服务器产品提供安全传输服务,现已成为保密通信的工业标准。
  TLS协议框架主要有2个层次的协议:TLS握手协议和TLS记录协议。TLS握手协议用来让服务器与客户在传输应用层数据之前交换TLS协议版本信息、协商加密算法、进行(相互)身份认证并交换密钥。TLS记录协议用来将应用层提供的信息进行分组、压缩、数据完整性检查和加密。数据完整性检查通过比较传输前后使用安全散列函数(如SHA和MD5 等)计算出来的数据的MAC值是否一致来完成。数据加密采用对称密码算法(如R4和DES等)。对数据进行完整性检查和加密的密钥由TLS握手协议来协商。
  XMPP中采用的STARTTLS扩展处理流程如下(C:客户端,S:TLS服务器):
  (1)C、S之间建立XML流会话连接。
  (2)S 向C 发送STARTTLS扩展服务需求及支持的其他认证机制列表,代码实例如下:
  <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>
  (3)C发送STARTTLS命令给S。
  (4)C、S中TLS握手协议开始协商相关加密算法及密钥。
  (5)若TLS握手协议协商成功,则关闭当前XML流会话,C发起一个新的XML流会话,所有传送的信息均被TLS记录协议加密。TLS握手协议协商不成功则发出警告信息。
  (6)S向C回复新XML流会话。
4  客户端程序设计中的关键问题
  由于网络中已存在大量的XMPP服务器,在一般的应用开发中,只要设计自定功能的客户端程序即可,并可以选用Smack库来加速开发。
  (1)创建一个XMPP连接。因为XMPP使用TCP协议,所以首先必须创建一个网络连接,XMPPConnection就是Smack库用来创建与XMPP服务器连接的类,创建一个XMPP连接的代码如下:
  XMPPConnection connection=new XMPPConnection(″jab-
ber.org″);
  如要创建加密连接,可以使用SSLXMPPConnection类:
  XMPPConnection connection=new SSLXMPPConnection(″jabber.org″);
  (2)登录。TCP连接创建后,需要使用用户名和密码登录到XMPP服务器,登录程序可以使用XMPPConnection.login(String username,String password)方法。登录后就可以和其他人聊天。
connection.login(″yb″,″password″);//connection为已创建的XMPP连接,下同
  connection.createChat(″yb@sdpt.com″).sendMessage
(″Hello!″);
  (3)操作名册。每个用户都包括:一个XMPP地址(如“yb@sdpt.com”)、名称或昵称(如″yb″),及其所属列表(如好友、同事等)。名册能够跟踪好友或某用户组是否在线及其状态信息,登录后,可以使用Roster类来取得好友或某用户组的状态,代码如下:
  Roster roster=con.getRoster( );
  for (Iterator i=roster.getEntries( );i.hasNext( ); ) {
  System.out.println(i.next( ));}
  名册信息通常是随时变化的,可能需要增加或删除。要监听名单及其在线状态的改变,可以使用RosterListener。
  (4)发送和接收消息。发送接收消息可以使用Chat和GroupChat类。下面介绍如何使用Chat发送文本消息,GroupChat的使用方法类似。
  Chat newChat=connection.createChat(″yb@sdpt.com″);//创建新Chat
  newChat.sendMessage(″Hello!″);//发送消息″Hello!″
  利用Chat.sendMessage( )方法可以方便地创建一个消息对象,它的参数就是消息内容,执行后消息会发送出去。Chat对象还能侦听对方的回应,下面的代码会将收到的任何消息返回给发送端。
  Chat newChat=connection.createChat(″yb@sdpt.com″);
  newMessage.setBody(″Hi, I′m waiting for you.″);
  while (true) {
  Message message=newChat.nextMessage( );//等待对方发送消息
  newChat.sendMessage(message.getBody());//把对方
  }//发送来的消息发回去
  (5)修改状态。要修改状态可以用presence.Type.UNAV-ILABLE作为参数创建一个presence,状态将改变为不在线状态。以下代码将修改为不在线状态,并告知溜冰去了:
  Presence presence=new Presence(Presence.Type.UNAVAILABLE);
  presence.setStatus(″Gone skating″);
5  结束语
  目前,全球有20万个即时通信平台支持XMPP,有1 000万人在使用。简单的接口、开放的协议、互联的架构、权威的标准再加上坚实的用户基础是XMPP的优势。相信XMPP将为即时通信技术的运用提供更为广阔的空间。
参考文献
1   Peter S A.XMPP Core.RFC 3920,2004
2   Peter S A.XMPP Instant Messaging and Presence.RFC 3921,2004
3   Dierks T,Allen C,Treese W et al.The TLS Protocol Version 1.0.RFC 2246,1999
4   Myers J.Simple Authentication and Security Layer.RFC  2222,1997
5   Kaes C.Definition of Jabber Identifiers (JIDs).JEP 0029,2003
6   Mealling M.The IETF XML Registry.RFC 3688,2004
 

此内容为AET网站原创,未经授权禁止转载。