飞信2010分析 – SIPC验证
?
飛信2010分析 – SIPC驗證
2010年4月3日?| 分類:?飛信哪些事兒?| 標簽:OK,接上文,繼續分析。
飛信登錄的第三部就是連接SIPC服務器,驗證并獲取好友列表等信息。
SIPC是什么含義呢? SIP是會話初始協議(Session initializtion Protocol),是一個標準的協議,其RFC可以在這里下載。協議的規定如何開始一個會話。通常和這個協議一起使用的還有SDP協議。
但飛信只用了SIP,并且把SIP協議做了一些拓展,所以后面有個C。C可能代表China Mobile。關于SIP協議的格式和移動在SIPC上的拓展和不同,請參照nathan2007的文章。這里就不多說了。
上文說過,飛信SIPC服務器的地址是在第一步獲取自適應配置中獲得,有三個配置有用。
含義????位置?????????結果舉例
標準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
從上面可以看出飛信支持三種連接方式,
標準SIPC連接方式就是直接連接服務器的8080端口,SIPC信令直接放在TCP包中,
SSLSIPC連接方式連接服務器的443端口,雖說連接的是443端口,卻沒有使用SSL加密,仍是明文傳輸,不做任何處理,和標準直連接沒有任何區別,只是端口號變了而已。
HTTP代理連接方式是在只能訪問80端口的情況下才啟用的連接方式,使用POST方式,SIPC信令就放在POST的數據包中,這個我會詳細的寫文章分析的。
可見飛信對網絡環境的適應能力是非常強的。基本能在限制比較多的網絡環境中登錄成功。還有個細節不知各位注意沒,標準直連接和HTTP連接是連接到同一個服務器上,這就需要這個服務器同時運行兩個服務:SIPC服務和WEB服務,這對服務器的穩定性和性能要求還是比較高的。
飛信客戶端連接到飛信SIPC服務器上后,在獲取好友列表等信息之前是需要完成驗證的。
首先是發起注冊請求。(姑且就這樣叫吧)
展開源代碼查看源代碼 打印關于 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"請求:這個請求主要是向服務器請求驗證的RSA公鑰
其中F是飛信號就是用戶uri中@前面的數字,如123456789@fetion.com.cn;p=1234,I是CallId,Q是Sequence,我仍然沒有找到規律。。。。(詳細說明IQ)
CN:是Cnoce,是客戶端隨機生成的16字節的16進制表示的字符串,可能服務器需要用這個來生成RSA的密鑰的吧,這個沒法驗證了,只能猜測
CL:是Client,發送的客戶端的版本號和平臺類型,固定
回復:RSA公鑰和一個隨機字符,用于登錄驗證
返回的狀態碼是401,需要驗證
nonce:這個就是一個服務器生成隨機字符串,可能根據請求中CN來生成,僅用于驗證,沒有含義。
key: 這個比較重要,RSA算法中的公鑰,使用16進制表示,轉換為字節數組后共131字節。后面的signature,也是16進制表示的字節數組,共128字節(256字符),在目前還沒有發現含義,至少在登錄過程中沒有使用,暫且忽略。
因為飛信驗證用到了RSA算法,我對算法也不是很懂,上百度google了一下,大致了解了點,可能部分朋友對RSA不熟,我也簡單的說明下吧。
RSA算法是第一個能同時用于加密和數字簽名的算法。安全性依賴于大素數分解。采用不對稱加密和解密。
RSA可以用于數據加密。首先服務器生成一個密鑰對:一個公鑰和私鑰,公鑰用于加密,私鑰用于解密。服務器保存好私鑰,然后把公鑰發送給客戶端,客戶端用這個公鑰加密一些數據,并發回給服務器,服務器用剛才保存的私鑰解密。公鑰是公開的,任何人都可以使用公鑰加密發送給服務器,但私鑰是不公開的,只有公鑰的發布才會持有,公鑰加密的信息只有私鑰才能解密。
可以看出,RSA可以保證數據在傳輸過程中的安全性,因為只有私鑰才能解密,即使知道了公鑰也沒用。
當然反過來用也行,私鑰加密過的數據,只有公鑰才能解密,這個可以用于數字簽名。
私鑰的參數很多,用不上就不說了,公鑰的參數有兩個:
modulus:128字節 加密系數,主要的參數
publicExponent:3字節 公共系數,一般是固定的,0×010001
詳細的RSA信息可以參考維基百科:http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
回到飛信。飛信主要用RSA來做數據加密。在注冊請求中返回的W頭域中的key就是RSA的公鑰,前64字節(也就是128個字符)是modulus,后面的3字節(6個字符)是publicExponent。使用這個公鑰來加密用戶密碼,nonce, Aeskey。下面會有詳細的說明。
給出從key中解析出公鑰的代碼
接下來就是很關鍵的一步,SIPC驗證注冊
展開源代碼查看源代碼 打印關于 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"/>.....上面說到驗證需要用的RSA,這里的response就是用第一步返回的key進行RSA加密后的結果。加密的內容只有三個數據:第一步服務器返回的nonce,V4加密過的密碼,AESkey。
注意這里的密碼是指用userid和明文密碼加密過后的結果(兩次sha1),AESkey是AES算法的密鑰,估計是加密或者解密用戶配置的,沒有做驗證,32字節,可以隨機生成就行了。
假設這里的用戶密碼v4加密后的結果和AESKey都是用16進制表示的,nonce別把當字符串看,
要加密的數據就是
data = hex2byteArray(password)+getUTF8ByteArray(nonce)+hex2byteArray(AESKey)
(+表示字符數組的連接)
注意nonce不是轉換為字節數組,而是獲取UTF8編碼的字節數組。我在這里郁悶了很久。。
rsakey = parsePublicKey(key);
resByteArray = RSAencrypt(data, rsakey);
response = byteArray2Hex(resByteArray);
response就是發送給服務器的結果。
后面的參數不是很重要,也簡單說一下吧,machine-code是指的是當前活動網卡的MAC地址,可以固定。caps可能是capbilities的縮寫,在HTTP連接方式下為ff,在直接連接和SSL連接方式下為1ff,user-info里面的信息可以從SSI登錄成功中得到,后面一大堆的version指的是本地數據的版本,類似于版本控制,如果和服務器的版本相同就不回復相應的信息了。可以固定的設置為0,后面還有presence,這個是登錄狀態的,不同的取值表示的含義不同:400-在線,0-隱身,600-忙碌,100-離開,desc可以對現在這個狀態加以描述,默認為空。
這里給出RSA加密方法(就是上面的encrypt()方法)
展開源代碼查看源代碼 打印關于 01./** 02.?* 使用RSA加密字節數組 03.?* @param publicKey? RSA公鑰 04.?* @param obj? 要加密的字節數組 05.?* @return byte[] 加密后的字節數組 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.}如果一切正常的話,服務器就會返回200,登錄成功。返回的數據很多。有登錄記錄,個人信息,好友分組,好友列表,個人配置等。當然,如果你驗證的時候傳遞了記錄的版本號,如果和服務器相同的話,服務器就不會返回數據了 。因為是XML格式的,很容易理解,不贅述了。
如果服務返回的是421 Extension Required,這就需要驗證了。
展開源代碼查看源代碼 打印關于 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="飛信發現您本次變更了登錄地點。為保證您的帳號安全,需要您輸入驗證碼,這可以防止惡意程序的自動登錄。" tips=""/></results>需要驗證的原因也給出來了。在上一篇文章中詳細的說明了如何獲取驗證圖片。這里也一樣。飛信SSI登錄和SIPC注冊的驗證圖片的獲取是同一個地址。
獲取驗證圖片需要一個參數alg,這里可以從SIP返回的W頭的algorithm中取得。
獲取圖片之后,得到了一個圖片編號,即pid和圖片數據,把圖片解碼出來保存為文件或者渲染到圖片控件并讓用戶識別后,會得到用戶輸入的驗證字符。
假設圖片pid為6cbcdacb-44c2-4bd3-82a3-07d9e2e3f967,用戶識別上面的字符為:qyxfyd。
獲取到這些信息之后,就可以再一次發起注冊請求,基本上和上一次的請求相同,只不過多了一個SIP頭,Verify。
重復第二步:SIPC驗證注冊
展開源代碼查看源代碼 打印關于 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就是驗證圖片的算法,chid就是圖片的pid。
如果很幸運,驗證成功,就會和上面的返回結果一樣,但假如用戶識別錯了,驗證失敗,就會返回420,如下
這也一樣,繼續上面的操作,獲取驗證圖片,提示用戶識別,再注冊驗證,直到登錄成功。
當上面的驗證成功之后,你當前已經是在線了,就可以向服務器發起其他請求了,比如添加好友,發送消息等等。假如還需要支持群,就需要獲取群列表,群成員消息。
但這個時候還不能收到好友的在線情況的,剛才只是返回了好友的列表,好友的狀態還是沒有發送過來,登錄之后如何處理才能獲得好友狀態,請留意我下篇文章。
更新記錄:
2010.04.27 修正了key的長度錯誤,以前寫的是67字節,修改為131字節,我沒有仔細數。。感謝 Felix指出!!
2010.05.05 添加文中缺少的encrypt方法,感謝 supertrouper指出!!
?
總結
以上是生活随笔為你收集整理的飞信2010分析 – SIPC验证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中format使用
- 下一篇: Ubuntu、CentOS、macOS测