XMPP--TSL的使用

上一篇 / 下一篇  2010-12-06 00:18:32 / 个人分类:XMPP

XMPP包含的一个保证流安全的方法来防止篡改和偷听.这个传输层安全协议[TLS]的频道加密方法, 模拟了类似的其他"STARTTLS"(见RFC 2595[USINGTLS])的扩展,如IMAP [IMAP], POP3 [POP3], and ACAP [ACAP]."STARTTLS"的扩展名字空间是'urn:ietf:params:xml:ns:xmpp- tls'.
一个给定域的管理员可以(MAY)要求客户端和服务器通信以及服务器之间通信时使用TLS,或者两者都要求。客户端应该(SHOULD)在尝试完成SASL (第六章)握手之前使用TLS,服务器应该(SHOULD)在两个域之间使用TLS 以保证服务器间通信的安全。
以下是使用规则:
一个遵守本协议的初始化实体必须(MUST)在初始化流的头信息中包含一个'version'属性并把值设为“1.0”。
如果TLS握手发生在两个服务器之间,除非服务器声称的DNS主机名已经被解析(见第十四章第四节Server-to-Server Communications),通信不能(MUST NOT)继续进行。
当一个遵守本协议的接收实体接收了一个初始化流(它的头信息中包含一个'version'属性并且值设为“1.0”),在发送应答流的的头信息(其中包含版本标记)之后,它必须发送(MUST)<starttls/>元素(名字空间为'urn:ietf:params:xml:ns:xmpp-tls')以及其他它支持的流特性。
如果初始化实体选择使用TLS,TLS握手必须在SASL握手之前完成;这个顺序用于帮助保护SASL握手时发送的认证信息的安全,同时可以在必要的时候在TLS握手之前为SASL外部机制提供证书。
TLS握手期间,一个实体不能(MUST NOT)在流的根元素中发送任何空格符号作为元素的分隔符(在下面的TLS示例中的任何空格符都仅仅是为了便于阅读);这个禁令用来帮助确保安全层字节精度。
接收实体必须(MUST)在发送<proceed/> 元素的关闭符号">" 之后立刻开始TLS协商。初始化实体必须(MUST)在从接收实体接收到<proceed/> 元素的关闭符号">" 之后立刻开始TLS协商。
初始化实体必须(MUST)验证接收实体出示的证书;关于证书验证流程参见Certificate Validation ( 第十四章第二节)。
证书必须(MUST)检查初始化实体(比如一个用户)提供的主机名;而不是通过DNS系统解析出来的主机名;例如,如果用户指定一个主机名"example.com"而一个DNS SRV [SRV]查询返回"im.example.com",证书必须(MUST)检查"example.com".如果任何种类的XMPP实体(例如客户端或服务器)的JID出现在一个证书里,它必须(MUST)表现为一个别名实体里面的UTF8字符串,存在于subjectAltName之中。如何使用[ASN.1] 对象标识符"id-on-xmppAddr" 定义在本文的第五章第一节第一小节。
如果TLS 握手成功了,接收实体必须(MUST)丢弃TLS 生效之前从初始化实体得到的任何不可靠的信息.
如果TLS 握手成功了,初始化实体必须(MUST)丢弃TLS 生效之前从接收实体得到的任何不可靠的信息.
如果TLS 握手成功了,接收实体不能(MUST NOT)在流重新开始的时候通过提供其他的流特性来向初始化实体提供STARTTLS 扩展.
如果TLS 握手成功了,初始化实体必须(MUST)继续进行SASL握手。
如果TLS 握手失败了,接收实体必须(MUST)终止XML流和相应的TCP连接。
关于必须(MUST)支持的机制,参照Mandatory-to-Implement Technologies (第十四章第七节) 。

当一个初始化实体用TLS保护一个和接收实体之间的流,其步骤如下:
初始化实体打开一个TCP连接,发送一个打开的XML流头信息(其'version'属性设置为"1.0")给接收实体以初始化一个流。
接收实体打开一个TCP连接,发送一个XML流头信息(其'version'属性设置为"1.0")给初始化实体作为应答。
接收实体向初始化实体提议STARTTLS范围(包括其他支持的流特性),如果TLS对于和接收实体交互是必需的,它应该(SHOULD)在<starttls/>元素中包含子元素<required/>.
初始化实体发出STARTTLS命令(例如, 一个符合'urn:ietf:params:xml:ns:xmpp-tls'名字空间的 <starttls/> 元素) 以通知接收实体它希望开始一个TLS握手来保护流。
接收实体必须(MUST)以'urn:ietf:params:xml:ns:xmpp-tls'名字空间中的<proceed/>元素或<failure/>元素应答。如果失败,接收实体必须(MUST)终止XML流和相应的TCP连接。如果继续进行,接收实体必须(MUST)尝试通过TCP连接完成TLS握手并且在TLS握手完成之前不能(MUST NOT)发送任何其他XML数据。
初始化实体和接收实体尝试完成TLS握手。(要符合\[TLS\]规范)
如果 TLS 握手不成功, 接收实体必须(MUST)终止 TCP 连接. 如果 TLS 握手成功, 初始化实体必须(MUST)发送给接收实体一个打开的XML流头信息来初始化一个新的流(先发送一个关闭标签</stream>是不必要的,因为接收实体和初始化实体必须(MUST)确保原来的流在TLS握手成功之后被关闭) 。
在从初始化实体收到新的流头信息之后,接收实体必须(MUST)发送一个新的XML流头信息给初始化实体作为应答,其中应包含可用的特性但不包含STATRTTLS特性。

客户端-服务器示例

以下例子展示一个客户端使用STARTTLS保护数据流 (注意: 以下步骤举例说明协议中的失败案例;在这个例子中它们并不详尽并且也不是必须被数据传输触发的).
步骤 1: 客户端初始化流给服务器:
   <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
步骤 2: 服务器发送一个流标签给客户端作为应答:
   <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='c2s_123' from='example.com' version='1.0'>
步骤 3: 服务器发送 STARTTLS 范围给客户端(包括验证机制和任何其他流特性):
   <stream:features>
     <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
       <required/>
     </starttls>
     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
       <mechanism>DIGEST-MD5</mechanism>
       <mechanism>PLAIN</mechanism>
     </mechanisms>
   </stream:features>
步骤 4: 客户端发送 STARTTLS 命令给服务器:
   <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
步骤 5: 服务器通知客户端可以继续进行:
   <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
步骤 5 (或者): 服务器通知客户端 TLS 握手失败并关闭流和TCP连接:
   <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
   </stream:stream>
步骤 6: 客户端和服务器尝试通过已有的TCP连接完成 TLS 握手.
步骤 7: 如果 TLS 握手成功, 客户端初始化一个新的流给服务器:
   <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
步骤 7 (或者): 如果 TLS 握手不成功, 服务器关闭 TCP 连接.
步骤 8: 服务器发送一个流头信息应答客户端,其中包括任何可用的流特性:
   <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='c2s_234' version='1.0'>
   <stream:features>
     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
       <mechanism>DIGEST-MD5</mechanism>
       <mechanism>PLAIN</mechanism>
       <mechanism>EXTERNAL</mechanism>
     </mechanisms>
   </stream:features>
步骤 9: 客户端继续 SASL 握手 (第六章).

服务器-服务器示例

以下例子展示两个服务器之间使用STARTTLS保护数据流 (注意: 以下步骤举例说明协议中的失败案例;在这个例子中它们并不详尽并且也不是必须被数据传输触发的).
步骤 1: Server1 初始化流给 Server2:
   <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
步骤 2: Server2 发送一个流标签给 Server1 作为应答:
   <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_123' version='1.0'>
步骤 3: Server2 发送 STARTTLS 范围给 Server1 ,包括验证机制和任何其他流特性:
   <stream:features>
     <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
       <required/>
     </starttls>
     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
       <mechanism>DIGEST-MD5</mechanism>
       <mechanism>KERBEROS_V4</mechanism>
     </mechanisms>
   </stream:features>
步骤 4: Server1 发送 STARTTLS 命令给 Server2:
   <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
步骤 5: Server2 通知 Server1 允许继续进行:
   <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
步骤 5 (或者): Server2 通知 Server1 TLS握手失败并关闭流:
   <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
   </stream:stream>
步骤 6: Server1 和 Server2 尝试通过 TCP 完成 TLS 握手.
步骤 7: 如果 TLS 握手成功, Server1 初始化一个新的流给 Server2:
   <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
步骤 7 (或者): 如果 TLS 握手不成功, Server2 关闭 TCP 连接.
步骤 8: Server2 发送一个包含任何可用流特性的流头信息给 Server1 :
   <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_234' version='1.0'>
   <stream:features>
     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
       <mechanism>DIGEST-MD5</mechanism>
       <mechanism>KERBEROS_V4</mechanism>
       <mechanism>EXTERNAL</mechanism>
     </mechanisms>
   </stream:features>
步骤 9: Server1 继续进行 SASL 握手(第六章).


TAG:

 

评分:0

我来说两句

日历

« 2024-05-07  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 86536
  • 日志数: 218
  • 书签数: 1
  • 建立时间: 2010-11-06
  • 更新时间: 2011-03-21

RSS订阅

Open Toolbar