日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

飞信2010分析 – SIPC验证

發(fā)布時(shí)間:2023/12/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 飞信2010分析 – SIPC验证 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

飛信2010分析 – SIPC驗(yàn)證

2010年4月3日?| 分類:?飛信哪些事兒?| 標(biāo)簽:

OK,接上文,繼續(xù)分析。
飛信登錄的第三部就是連接SIPC服務(wù)器,驗(yàn)證并獲取好友列表等信息。
SIPC是什么含義呢? SIP是會(huì)話初始協(xié)議(Session initializtion Protocol),是一個(gè)標(biāo)準(zhǔn)的協(xié)議,其RFC可以在這里下載。協(xié)議的規(guī)定如何開始一個(gè)會(huì)話。通常和這個(gè)協(xié)議一起使用的還有SDP協(xié)議。
但飛信只用了SIP,并且把SIP協(xié)議做了一些拓展,所以后面有個(gè)C。C可能代表China Mobile。關(guān)于SIP協(xié)議的格式和移動(dòng)在SIPC上的拓展和不同,請(qǐng)參照nathan2007的文章。這里就不多說(shuō)了。

上文說(shuō)過(guò),飛信SIPC服務(wù)器的地址是在第一步獲取自適應(yīng)配置中獲得,有三個(gè)配置有用。
含義????位置?????????結(jié)果舉例
標(biāo)準(zhǔn)SIPC直連接?/config/server/sipc-proxy???221.130.46.141:8080
SSLSIPC連接??/config/server/sipc-ssl-proxy??221.130.46.141:443
HTTP代理連接? ?/config/server/http-tunnel???HTTP://221.130.46.141/ht/sd.aspx

從上面可以看出飛信支持三種連接方式,
標(biāo)準(zhǔn)SIPC連接方式就是直接連接服務(wù)器的8080端口,SIPC信令直接放在TCP包中,
SSLSIPC連接方式連接服務(wù)器的443端口,雖說(shuō)連接的是443端口,卻沒(méi)有使用SSL加密,仍是明文傳輸,不做任何處理,和標(biāo)準(zhǔn)直連接沒(méi)有任何區(qū)別,只是端口號(hào)變了而已。
HTTP代理連接方式是在只能訪問(wèn)80端口的情況下才啟用的連接方式,使用POST方式,SIPC信令就放在POST的數(shù)據(jù)包中,這個(gè)我會(huì)詳細(xì)的寫文章分析的。

可見飛信對(duì)網(wǎng)絡(luò)環(huán)境的適應(yīng)能力是非常強(qiáng)的。基本能在限制比較多的網(wǎng)絡(luò)環(huán)境中登錄成功。還有個(gè)細(xì)節(jié)不知各位注意沒(méi),標(biāo)準(zhǔn)直連接和HTTP連接是連接到同一個(gè)服務(wù)器上,這就需要這個(gè)服務(wù)器同時(shí)運(yùn)行兩個(gè)服務(wù):SIPC服務(wù)和WEB服務(wù),這對(duì)服務(wù)器的穩(wěn)定性和性能要求還是比較高的。

飛信客戶端連接到飛信SIPC服務(wù)器上后,在獲取好友列表等信息之前是需要完成驗(yàn)證的。

首先是發(fā)起注冊(cè)請(qǐng)求。(姑且就這樣叫吧)

展開源代碼查看源代碼 打印關(guān)于 01.R fetion.com.cn SIP-C/4.0 02.F: 123456789 03.I: 1 04.Q: 1 R 05.CN: 441F7DBA5C3153B61C0660C622F01354 06.CL: type="pc" ,version="3.6.1860" 07.------- 08.SIP-C/4.0 401 Unauthoried 09.F: 123456789 10.I: 1 11.Q: 1 R 12.W: Digest algorithm="SHA1-sess-v4",nonce="11F38E891D330436110471D742A7C08E",key="CAE3B6C60FC46B7A6FE4316FBABD4E9CC21DD01E330CE449F5BA46818A51F589C7ECD548BC4F6D8AA20BDA43FC75F89164E8EB70A20348251AB56B0059452508A516C955BE1463C1B7D82ED97CEDBD03DFD1DF7C5368FF1636A34E855B10BD19B6624DC68BC921771BE8C5F1E3EE1E5EBB1DB41CF1D0CB4BA41FACC2A54D6AF9010001",signature="57F1AD6CA5082C9BAA8DE5DD5521149903E9A85E4BDC9BE89CEFE39313DF836319E546AF01FE006F40B7243EF2099D813AEC746EDAE4C4003AAA88A1DBE6302C20505784D2458F0510B596D9DC32E2BF4E609BCF18EE46822B84D6EACDD463E0833E5D1CEBF6864920E6CB126456DF9A063385AC9828A34467AEDFEFA2B347A2"

請(qǐng)求:這個(gè)請(qǐng)求主要是向服務(wù)器請(qǐng)求驗(yàn)證的RSA公鑰
其中F是飛信號(hào)就是用戶uri中@前面的數(shù)字,如123456789@fetion.com.cn;p=1234,I是CallId,Q是Sequence,我仍然沒(méi)有找到規(guī)律。。。。(詳細(xì)說(shuō)明IQ)
CN:是Cnoce,是客戶端隨機(jī)生成的16字節(jié)的16進(jìn)制表示的字符串,可能服務(wù)器需要用這個(gè)來(lái)生成RSA的密鑰的吧,這個(gè)沒(méi)法驗(yàn)證了,只能猜測(cè)
CL:是Client,發(fā)送的客戶端的版本號(hào)和平臺(tái)類型,固定

回復(fù):RSA公鑰和一個(gè)隨機(jī)字符,用于登錄驗(yàn)證
返回的狀態(tài)碼是401,需要驗(yàn)證
nonce:這個(gè)就是一個(gè)服務(wù)器生成隨機(jī)字符串,可能根據(jù)請(qǐng)求中CN來(lái)生成,僅用于驗(yàn)證,沒(méi)有含義。
key: 這個(gè)比較重要,RSA算法中的公鑰,使用16進(jìn)制表示,轉(zhuǎn)換為字節(jié)數(shù)組后共131字節(jié)。后面的signature,也是16進(jìn)制表示的字節(jié)數(shù)組,共128字節(jié)(256字符),在目前還沒(méi)有發(fā)現(xiàn)含義,至少在登錄過(guò)程中沒(méi)有使用,暫且忽略。

因?yàn)轱w信驗(yàn)證用到了RSA算法,我對(duì)算法也不是很懂,上百度google了一下,大致了解了點(diǎn),可能部分朋友對(duì)RSA不熟,我也簡(jiǎn)單的說(shuō)明下吧。
RSA算法是第一個(gè)能同時(shí)用于加密和數(shù)字簽名的算法。安全性依賴于大素?cái)?shù)分解。采用不對(duì)稱加密和解密。
RSA可以用于數(shù)據(jù)加密。首先服務(wù)器生成一個(gè)密鑰對(duì):一個(gè)公鑰和私鑰,公鑰用于加密,私鑰用于解密。服務(wù)器保存好私鑰,然后把公鑰發(fā)送給客戶端,客戶端用這個(gè)公鑰加密一些數(shù)據(jù),并發(fā)回給服務(wù)器,服務(wù)器用剛才保存的私鑰解密。公鑰是公開的,任何人都可以使用公鑰加密發(fā)送給服務(wù)器,但私鑰是不公開的,只有公鑰的發(fā)布才會(huì)持有,公鑰加密的信息只有私鑰才能解密。
可以看出,RSA可以保證數(shù)據(jù)在傳輸過(guò)程中的安全性,因?yàn)橹挥兴借€才能解密,即使知道了公鑰也沒(méi)用。
當(dāng)然反過(guò)來(lái)用也行,私鑰加密過(guò)的數(shù)據(jù),只有公鑰才能解密,這個(gè)可以用于數(shù)字簽名。
私鑰的參數(shù)很多,用不上就不說(shuō)了,公鑰的參數(shù)有兩個(gè):
modulus:128字節(jié) 加密系數(shù),主要的參數(shù)
publicExponent:3字節(jié) 公共系數(shù),一般是固定的,0×010001
詳細(xì)的RSA信息可以參考維基百科:http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

回到飛信。飛信主要用RSA來(lái)做數(shù)據(jù)加密。在注冊(cè)請(qǐng)求中返回的W頭域中的key就是RSA的公鑰,前64字節(jié)(也就是128個(gè)字符)是modulus,后面的3字節(jié)(6個(gè)字符)是publicExponent。使用這個(gè)公鑰來(lái)加密用戶密碼,nonce, Aeskey。下面會(huì)有詳細(xì)的說(shuō)明。
給出從key中解析出公鑰的代碼

展開源代碼查看源代碼 打印關(guān)于 01./** 02.?* 從服務(wù)器返回的key字符串解析出RSA公鑰 03.?* @param publicKey???? 服務(wù)器返回的key字符串 04.?* @return? 解析出來(lái)的RSA公鑰,可以用這個(gè)公鑰加密數(shù)據(jù) 05.?* @throws NoSuchAlgorithmException 06.?* @throws InvalidKeySpecException 07.?*/ 08.private?RSAPublicKey parsePublicKey(String publicKey)?throwsNoSuchAlgorithmException, InvalidKeySpecException 09.{ 10.????String modulusText? = publicKey.substring(0,0x100); 11.????String exponentText = publicKey.substring(0x100); 12.????BigInteger modulus? =?new?BigInteger(1, ConvertHelper.hexString2ByteNoSpace(modulusText)); 13.????BigInteger exponent =?new?BigInteger(1, ConvertHelper.hexString2ByteNoSpace(exponentText)); 14.????KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 15.????RSAPublicKeySpec bobPubKeySpec =?new?RSAPublicKeySpec(modulus, exponent); 16.????RSAPublicKey rsapublicKey = (RSAPublicKey) keyFactory.generatePublic(bobPubKeySpec); 17.????return??rsapublicKey; 18.}

接下來(lái)就是很關(guān)鍵的一步,SIPC驗(yàn)證注冊(cè)

展開源代碼查看源代碼 打印關(guān)于 01.R fetion.com.cn SIP-C/4.0 02.F: 123456789 03.I: 1 04.Q: 2 R 05.A: Digest response="6AC3FEE164709828DCDBA1FC71BAFE9FDD83980DA83959E0993912EA74BF836BC76F196F9C99BD71F64732C00BEEEC1A516C134B637EEFA71BBAF26447B5B310BE3BC3A58FD2E6B22094F16B1CF85F2E5B6AD5C9A60FF6055C7DD8C476A28C97C7A6876176C5EF738FC21CEACB400190B1BF538EC930429DED246F49A9CE7C90",algorithm="SHA1-sess-v4" 06.AK: ak-value 07.L: 428 08.? 09.<args><device machine-code="001D0936BCB6" /><caps value="1ff" /><events value="7f" /><user-info mobile-no="159xxxxxx" user-id="987654321"><personal version="0" attributes="v4default" /><custom-config version="0" /><contact-list version="0"?? buddy-attributes="v4default" /></user-info><credentials domains="fetion.com.cn;m161.com.cn;www.ikuwa.cn;games.fetion.com.cn" /><presence><basic value="400" desc="" /></presence></args> 10.------ 11.SIP-C/4.0 200 OK 12.I: 1 13.Q: 2 R 14.X: 600 15.L: 12545 16.? 17.<results><client public-ip="222.210.18.145" login-place="" last-login-ip="222.210.26.134" last-login-place="" last-login-time="4/1/2010 7:55:38 PM"/>.....

上面說(shuō)到驗(yàn)證需要用的RSA,這里的response就是用第一步返回的key進(jìn)行RSA加密后的結(jié)果。加密的內(nèi)容只有三個(gè)數(shù)據(jù):第一步服務(wù)器返回的nonce,V4加密過(guò)的密碼,AESkey。
注意這里的密碼是指用userid和明文密碼加密過(guò)后的結(jié)果(兩次sha1),AESkey是AES算法的密鑰,估計(jì)是加密或者解密用戶配置的,沒(méi)有做驗(yàn)證,32字節(jié),可以隨機(jī)生成就行了。
假設(shè)這里的用戶密碼v4加密后的結(jié)果和AESKey都是用16進(jìn)制表示的,nonce別把當(dāng)字符串看,
要加密的數(shù)據(jù)就是
data = hex2byteArray(password)+getUTF8ByteArray(nonce)+hex2byteArray(AESKey)
(+表示字符數(shù)組的連接)
注意nonce不是轉(zhuǎn)換為字節(jié)數(shù)組,而是獲取UTF8編碼的字節(jié)數(shù)組。我在這里郁悶了很久。。
rsakey = parsePublicKey(key);
resByteArray = RSAencrypt(data, rsakey);
response = byteArray2Hex(resByteArray);
response就是發(fā)送給服務(wù)器的結(jié)果。

展開源代碼查看源代碼 打印關(guān)于 01./** 02.?* 生成加密結(jié)果 03.?* @param publicKey???? RSA公鑰,從返回的W頭部的key獲取值,16進(jìn)制表示的字節(jié)數(shù)組 67Bytes(134Chars) 04.?* @param password????? V4加密的密碼,指用userid和明文密碼加密過(guò)后的結(jié)果(兩次sha1),16進(jìn)制表示的字節(jié)數(shù)組 20Bytes(40Chars) 05.?* @param nonce???????? 服務(wù)器返回的隨機(jī)字符串,看做字符串 16Bytes(32Chars) 06.?* @param aeskey??????? AES算法的密鑰,估計(jì)是加密或者解密用戶配置的 32Bytes(64Chars) 07.?* @return????????????? 生成的結(jié)果,16進(jìn)制表示的字節(jié)數(shù)組 08.?* @throws NoSuchAlgorithmException 09.?* @throws InvalidKeySpecException 10.?*/ 11.public?String generate(String publicKey, String password, String nonce, String aeskey)throws?NoSuchAlgorithmException, InvalidKeySpecException 12.{ 13.????byte[] pb = ConvertHelper.hexString2ByteNoSpace(password); 14.????byte[] nb = ConvertHelper.string2Byte(nonce); 15.????byte[] ab = ConvertHelper.hexString2ByteNoSpace(aeskey); 16.? 17.????byte[] res =?new?byte[pb.length+nb.length+ab.length]; 18.????System.arraycopy(nb,?0, res,?0, nb.length); 19.????System.arraycopy(pb,?0, res, nb.length, pb.length); 20.????System.arraycopy(ab,?0, res, pb.length+nb.length, ab.length); 21.? 22.????byte[] some = encrypt(parsePublicKey(publicKey), res); 23.? 24.????return?ConvertHelper.byte2HexStringWithoutSpace(some); 25.}

后面的參數(shù)不是很重要,也簡(jiǎn)單說(shuō)一下吧,machine-code是指的是當(dāng)前活動(dòng)網(wǎng)卡的MAC地址,可以固定。caps可能是capbilities的縮寫,在HTTP連接方式下為ff,在直接連接和SSL連接方式下為1ff,user-info里面的信息可以從SSI登錄成功中得到,后面一大堆的version指的是本地?cái)?shù)據(jù)的版本,類似于版本控制,如果和服務(wù)器的版本相同就不回復(fù)相應(yīng)的信息了。可以固定的設(shè)置為0,后面還有presence,這個(gè)是登錄狀態(tài)的,不同的取值表示的含義不同:400-在線,0-隱身,600-忙碌,100-離開,desc可以對(duì)現(xiàn)在這個(gè)狀態(tài)加以描述,默認(rèn)為空。

這里給出RSA加密方法(就是上面的encrypt()方法)

展開源代碼查看源代碼 打印關(guān)于 01./** 02.?* 使用RSA加密字節(jié)數(shù)組 03.?* @param publicKey? RSA公鑰 04.?* @param obj? 要加密的字節(jié)數(shù)組 05.?* @return byte[] 加密后的字節(jié)數(shù)組 06.?*/ 07.protected?byte[] encrypt(RSAPublicKey publicKey,?byte[] obj) { 08.????if?(publicKey !=?null) { 09.????????try?{ 10.????????????Cipher cipher = Cipher.getInstance("RSA"); 11.????????????cipher.init(Cipher.ENCRYPT_MODE, publicKey); 12.????????????return?cipher.doFinal(obj); 13.????????}?catch?(Exception e){ 14.????????????e.printStackTrace(); 15.????????} 16.????} 17.????return?null; 18.}

如果一切正常的話,服務(wù)器就會(huì)返回200,登錄成功。返回的數(shù)據(jù)很多。有登錄記錄,個(gè)人信息,好友分組,好友列表,個(gè)人配置等。當(dāng)然,如果你驗(yàn)證的時(shí)候傳遞了記錄的版本號(hào),如果和服務(wù)器相同的話,服務(wù)器就不會(huì)返回?cái)?shù)據(jù)了 。因?yàn)槭?#xff38;ML格式的,很容易理解,不贅述了。

如果服務(wù)返回的是421 Extension Required,這就需要驗(yàn)證了。

展開源代碼查看源代碼 打印關(guān)于 1.SIP-C/4.0 421 Extension Required 2.I: 1 3.Q: 2 R 4.W: Verify algorithm="picc-ChangeMachine",type="GeneralPic" 5.L: 191 6.? 7.<results><reason text="飛信發(fā)現(xiàn)您本次變更了登錄地點(diǎn)。為保證您的帳號(hào)安全,需要您輸入驗(yàn)證碼,這可以防止惡意程序的自動(dòng)登錄。" tips=""/></results>

需要驗(yàn)證的原因也給出來(lái)了。在上一篇文章中詳細(xì)的說(shuō)明了如何獲取驗(yàn)證圖片。這里也一樣。飛信SSI登錄和SIPC注冊(cè)的驗(yàn)證圖片的獲取是同一個(gè)地址。
獲取驗(yàn)證圖片需要一個(gè)參數(shù)alg,這里可以從SIP返回的W頭的algorithm中取得。
獲取圖片之后,得到了一個(gè)圖片編號(hào),即pid和圖片數(shù)據(jù),把圖片解碼出來(lái)保存為文件或者渲染到圖片控件并讓用戶識(shí)別后,會(huì)得到用戶輸入的驗(yàn)證字符。

假設(shè)圖片pid為6cbcdacb-44c2-4bd3-82a3-07d9e2e3f967,用戶識(shí)別上面的字符為:qyxfyd。
獲取到這些信息之后,就可以再一次發(fā)起注冊(cè)請(qǐng)求,基本上和上一次的請(qǐng)求相同,只不過(guò)多了一個(gè)SIP頭,Verify。

重復(fù)第二步:SIPC驗(yàn)證注冊(cè)

展開源代碼查看源代碼 打印關(guān)于 01.R fetion.com.cn SIP-C/4.0 02.F: 123456789 03.I: 1 04.Q: 2 R 05.A: Digest response="3C10B5F148EA52FB42441F640D235D27556920D6753624C8CDABFC0254FCDA89522A5B72FE37BC8D828BF9B7EBB1859B8BB4558D56A83115E724541B4B34316B4F56BBD76002EBDB44AC2E65FC000913E737242A12CB52A6B83A3EE6F38AD36DDEA2528667CDE547DBF57A40E7529D75096835AB621F56750B9857614836C43D",algorithm="SHA1-sess-v4" 06.AK: ak-value 07.A: Verify response="qyxfyd",algorithm="picc-ChangeMachine",type="GeneralPic",chid="6cbcdacb-44c2-4bd3-82a3-07d9e2e3f967" 08.L: 436 09.? 10.<args><device machine-code="001D0936BCB6" /><caps value="1ff" /><events value="7f" /><user-info mobile-no="159xxxxxx" user-id="987654321"><personal version="0" attributes="v4default" /><custom-config version="318214543" /><contact-list version="0"?? buddy-attributes="v4default" /></user-info><credentials domains="fetion.com.cn;m161.com.cn;www.ikuwa.cn;games.fetion.com.cn" /><presence><basic value="400" desc="" /></presence></args>

很容易看出Verify頭中,response就是用戶輸入的字符串,algorithm就是驗(yàn)證圖片的算法,chid就是圖片的pid。
如果很幸運(yùn),驗(yàn)證成功,就會(huì)和上面的返回結(jié)果一樣,但假如用戶識(shí)別錯(cuò)了,驗(yàn)證失敗,就會(huì)返回420,如下

展開源代碼查看源代碼 打印關(guān)于 1.SIP-C/4.0 420 Bad Extension 2.F: 685592830 3.I: 1 4.Q: 2 R 5.W: Verify algorithm="picc-ChangeMachine",type="GeneralPic" 6.L: 191 7.? 8.<results><reason text="飛信發(fā)現(xiàn)您本次變更了登錄地點(diǎn)。為保證您的帳號(hào)安全,需要您輸入驗(yàn)證碼,這可以防止惡意程序的自動(dòng)登錄。" tips=""/></results>

這也一樣,繼續(xù)上面的操作,獲取驗(yàn)證圖片,提示用戶識(shí)別,再注冊(cè)驗(yàn)證,直到登錄成功。

當(dāng)上面的驗(yàn)證成功之后,你當(dāng)前已經(jīng)是在線了,就可以向服務(wù)器發(fā)起其他請(qǐng)求了,比如添加好友,發(fā)送消息等等。假如還需要支持群,就需要獲取群列表,群成員消息。
但這個(gè)時(shí)候還不能收到好友的在線情況的,剛才只是返回了好友的列表,好友的狀態(tài)還是沒(méi)有發(fā)送過(guò)來(lái),登錄之后如何處理才能獲得好友狀態(tài),請(qǐng)留意我下篇文章。

更新記錄:
2010.04.27 修正了key的長(zhǎng)度錯(cuò)誤,以前寫的是67字節(jié),修改為131字節(jié),我沒(méi)有仔細(xì)數(shù)。。感謝 Felix指出!!
2010.05.05 添加文中缺少的encrypt方法,感謝 supertrouper指出!!

?

總結(jié)

以上是生活随笔為你收集整理的飞信2010分析 – SIPC验证的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。