您的位置:首页 > 运维架构

openfire用户验证知多少

2015-09-23 11:30 267 查看

一、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

注意了:基于xml的sasl对话,需要把内容信息经过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进行加密,最后保存到数据库中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: