openfire用户验证知多少

一、SASL概念

       1、SASL跟OF什么关系?

Openfire(简称of),他是基于XMPP协议开发的,XMPP架构如下:

 

       2、SASL到底是什么?

       引用百度百科的废话:http://baike.baidu.com/view/1014674.htm

SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。在Postfix可以利用SASL来判断用户是否有权使用转发服务,或是辨认谁在使用你的服务器。

SASL提供了一个通用的方法为基于连接的协议增加验证支持,而XMPP使用了一个普通的XML名字空间来满足SASL的需要

       说白了,就是一种身份验证机制,鉴权用户的身份用。一般很多网站验证身份也就是提交用户名和密码,服务端进行判断即可。SASL他也一样,只不过他的传输的内容多样化了。

      

      3、SASL流程是如何的?

SASL验证方式多样化,有如下方式:CRAM-MD5, EXTERNAL, GSSAPI, ANONYMOUS, PLAIN, SECURID, DIGEST-MD5, LOGIN, NTLM。

of他支持哪些方式了?来看看of发送的东西:

<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>CRAM-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register
xmlns="http://jabber.org/features/iq-register"/></stream:features>

看看上面黄色底部的,他支持了SASL四种验证机制。

我使用DIGEST-MD5看流程:

Of服务端:“喂,您好我有上面四种验证方式,你来选择一种告诉我吧”。

Of客户端:“老大,我要选择DIGEST-MD5”
       <auth mechanism="DIGEST-MD5" ></auth>

Of服务端:“很好,来,我发送一个质询给你——其实就是用来加密的一些参数数据和加密算法,内容是:

realm="gsd",nonce="r52TbJKIRFuhMEahubcX9q1l35CtNWP22mf3eYCr",qop="auth",charset=utf-8,algorithm=md5-sess

注意了:基于xmlsasl对话,需要把内容信息经过base64编码,服务端发送了一个唯一的临时信息“nonce”,只能使用在一次验证中。

Of客户端:“好的,我将根据你发送过来的信息,对我的用户名和密码进行加密,得到一个值放在response(key)给你哈。等等”

发送的内容是:

charset=utf-8,username="*****",realm="gsd",nonce="r52TbJKIRFuhMEahubcX9q1l35CtNWP22mf3eYCr",nc=00000001,cnonce="9RvMVSw2INjosXIoTV09ycC8UPRDpWnPhXbSn/XW",digest-uri="xmpp/gsd",maxbuf=65536,response=1de05c0734e4aaf391a220eaca5e7b35,qop=auth,authzid="*****"

其中,这个非常重要:response=1de05c0734e4aaf391a220eaca5e7b35,他是根据什么来计算出来的了?

DIGEST-MD5算法,使用的参数数据有:cnonce,qop,nc,digest-uri,ha1,而

其中ha1这个值就是通过md5-sess这个算法来计算出来的,所需要的参数是: realm值,nonce,用户名,用户名密码,cononce。(md5-sess和md5应用上最大的区别,一个需要密钥,另一个不需要密钥)

Of服务端:“客户端兄弟,我收到你的数据了,我将从数据库中获取出该用户的密码,然后也根据我约定的algorithm=md5-sess算法进行加密(参数跟客户端加入的一模一样)得出response值,看看是否等于你发送过来的
response=1de05c0734e4aaf391a220eaca5e7b35,如果是相同,那么该用户就可以登录了,我将反馈一个信息给你:
<success>rspauth=bdbf055a7f60947a2c2d71760e84e38b</success>。告诉你用户登录成功了”

      

4、SASL优势——digest-md5

密码不用在网络上传输,而且验证过程所交换的密钥只能使用一次。

二、android版本接口包的bug

问题描述:我们在开发过程使用上面的digest-md5 SASL验证方式验证用户登录,但是老是登录不成功。

问题在于:因为我们使用邮箱包含@,而xmpp中@的有特殊含义,所以在传输过程邮箱的@需要被转义成\40。但是asmack没有对”\”认真处理直接把邮箱的值放入到response中,而这个邮箱值是带引号的,会自动对\进行转义。

来看看asmck的粗心的地方:

digestResponse.append("username=\"");

digestResponse.append(m_authorizationId);

如果m_authorizationId=”haiji\\40163.com.cn”,他放入到“”中,会变成haiji\40163.com.cn少了一个\,到服务端他得到的是”haiji\40163.com.cn”,但他到服务端又是在引号里面,又需要对\转义变成了haiji163.com.cn,出错了。

正确的做法,应该看http://www.docjar.com/html/api/com/sun/security/sasl/digest/DigestMD5Client.java.html这里面的代码:

digestResponse.append("username=\"");

digestResponse.append(quotedStringValue(m_authorizationId));

三、快速对称加密算法——blowfish

       1、对称加密算法

说白了密钥是相同的,非对称密钥是不相同的(RSA),逆向加密算法(md5)加密后不能还原的

2、什么是Blowfish算法

跟着百度来解读吧:

百度上面说blowfish算法是用来加密64bit分组(怎么分组?采用cbc模式——具体内容看我之前的文章《加密算法研究.docx》)长度的字符串,如果某一个字符串长度不够了?或者长度超过超过了怎么办?请看我的文章关于补位方面的知识《加密算法研究.docx》。

Blowfish算法有两个盒子unsignedlongpbox和unsignedlongsbox,这两个盒子是根据源密钥pbox和sbox跟我们用户提交的密钥变换得到的。Pbox和sbox是固定的,sbox他是根据“π”来生成的。具体流程:

P数组由18个32位子密钥组成:
  P1,P2,P3,……P18
  4个32位的S盒,每个有256个单元:
  S[1,0],S[1,1],S[1,2],……S[1,255]
  S[2,0],S[2,1],S[2,2],……S[2,255]
  S[3,0],S[3,1],S[3,2],……S[3,255]
  S[4,0],S[4,1],S[4,2],……S[4,255]
  计算过程如下:
  1.初始化P数组,然后是4个S盒用固定的串.这些串由π的十六进制组成.
  2.用密钥的第一个32位与P1异或,用密钥的第二个32位与P2异或,依此类推,直到密钥的所有位(直到P18).周期性地循环密钥的所有位直到整个P数组与密钥异或完为止.
  3.利用Blowfish算法加密全零串,其密钥为在第1和第2步中描述的子密钥.
  4.用第3步的输出取代P1和P2.
  5.利用Blowfish算法加密第3步的输出,其密钥为修改过的子密钥.
  6.用第5步的输出取代P3和P4.
  7.重重上述操作,直到P数组的所有元素及4个S盒全部被连续变化的Blowfish的输出所取代.
  Blowfish是一个由16轮构成的Feistel结构.输入是64位数据x,加密过程为:
  把x分成32位的两部分:xL,xR
  对于i=1至16
  xL=xL^Pi
  xR=F(xL)^xR
  交换xL和xR(最后一轮取消该运算)
  xR=xR^P17
  xL=xL^P18
  重新合并xL和xR

 

四、Blowfish家住of

    Of的blowfish密钥放在哪里?请查看数据库ofProperty

 

 

五、遗留问题以及改进

1、【问题】Of为什么采用blowfish保存密码?这个待考证……

密码应该尽量使用单向散列算法的

        2、【解决】

       目前我们要求是对密码先使用base64(HMAC-SH1(password))得到单向的散列字符串,然后在使用blowfish进行加密,最后保存到数据库中。

猜你喜欢

转载自gsdhaiji-cai.iteye.com/blog/1836758