这几天了解了一下msn协议的登陆部分,凑了几段代码实现了,有资料的话没什么难度,主要是了解一下相关的过程和机制。下面模拟的是msn 8.5.1238 版本(实际上就是抓包然后填到程序里)
废话少说,直接开始吧(细节不说了,自己补课)
首先登陆DS服务器:messenger.hotmail.com:1863
VER 1 MSNP15 MSNP14 MSNP13 CVR0
VER 1 MSNP15 MSNP14 MSNP13 CVR0
CVR 2 0x0804 winnt 5.1 i386 MSG80BETA 8.5.1238 msmsgs test@hotmail.com
USR 3 SSO I test@hotmail.com
CVR 2 8.1.0178 8.1.0178 8.1.0178 http://msgruser.dlservice.microsoft.com/download/B/D/3/BD343317-2DBF-48FE-8BD9-9E3212D65E6A/Install_Messenger.exe http://get.live.com/cn
XFR 3 NS 207.46.108.67:1863 U D
< Envelope xmlns ="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse ="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:saml ="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp ="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wsu ="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wssc ="http://schemas.xmlsoap.org/ws/2004/04/sc" xmlns:wst ="http://schemas.xmlsoap.org/ws/2004/04/trust" >
< Header >
< ps:AuthInfo xmlns:ps ="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id ="PPAuthInfo" >
< ps:HostingApp > {7108E71A-9926-4FCB-BCC9-9A9D3F32E423} </ ps:HostingApp >
< ps:BinaryVersion > 4 </ ps:BinaryVersion >
< ps:UIVersion > 1 </ ps:UIVersion >
< ps:Cookies />
< ps:RequestParams > AQAAAAIAAABsYwQAAAAyMDUy </ ps:RequestParams >
</ ps:AuthInfo >
< wsse:Security >
< wsse:UsernameToken Id ="user" >
< wsse:Username > test@hotmail.com </ wsse:Username >
< wsse:Password > test </ wsse:Password >
</ wsse:UsernameToken >
</ wsse:Security >
</ Header >
< Body >
< ps:RequestMultipleSecurityTokens xmlns:ps ="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id ="RSTS" >
< wst:RequestSecurityToken Id ="RST0" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > http://Passport.NET/tb </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
</ wst:RequestSecurityToken >
< wst:RequestSecurityToken Id ="RST1" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > messengerclear.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="MBI_KEY_OLD" />
</ wst:RequestSecurityToken >
< wst:RequestSecurityToken Id ="RST2" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > messenger.msn.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="?id=507" />
</ wst:RequestSecurityToken >
< wst:RequestSecurityToken Id ="RST3" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > contacts.msn.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="MBI" />
</ wst:RequestSecurityToken >
< wst:RequestSecurityToken Id ="RST4" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > messengersecure.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="MBI_SSL" />
</ wst:RequestSecurityToken >
< wst:RequestSecurityToken Id ="RST5" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > spaces.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="MBI" />
</ wst:RequestSecurityToken >
< wst:RequestSecurityToken Id ="RST6" >
< wst:RequestType > http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > storage.msn.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="MBI" />
</ wst:RequestSecurityToken >
</ ps:RequestMultipleSecurityTokens >
</ Body >
</ Envelope >
注意其中的
< wst:RequestType > http://schemas.xmlsoap.org/... </ wst:RequestType >
< wsp:AppliesTo >
< wsa:EndpointReference >
< wsa:Address > messengersecure.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wsse:PolicyReference URI ="MBI_SSL" />
</ wst:RequestSecurityToken >
每一个RST对应于一个服务,比如上面这个就是messengersecure.live.com了。一般会有下面几个:
messengerclear.live.com:用于msn的认证
messenger.msn.com:msn网页认证
contacts.msn.com:Contact server 的认证
spaces.msn.com:msn spaces 的认证
当然,最重要的别忘了填入用户名和密码^_^
POST成功以后,接收服务器返回的内容,也是xml的:
< S:Envelope xmlns:S ="http://schemas.xmlsoap.org/soap/envelope/" >
< S:Header >
< psf:pp xmlns:psf ="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault" >
< psf:serverVersion > 1 </ psf:serverVersion >
< psf:PUID > 00067FFEA125C93F </ psf:PUID >
< psf:configVersion > 4.0.5633.0 </ psf:configVersion >
< psf:uiVersion > 3.100.2179.0 </ psf:uiVersion >
< psf:authstate > 0x48803 </ psf:authstate >
< psf:reqstatus > 0x0 </ psf:reqstatus >
< psf:serverInfo Path ="Live1" RollingUpgradeState ="ExclusiveNew" LocVersion ="0" ServerTime ="2007-09-13T01:41:28Z" > BAYPPLOG2A06 2007.07.10.00.04.54 </ psf:serverInfo >
< psf:cookies />
< psf:browserCookies >
< psf:browserCookie Name ="MH" URL ="http://www.msn.com" > MH=; path=/; domain=.msn.com; expires=Wed, 30-Dec-2037 16:00:00 GMT </ psf:browserCookie >
< psf:browserCookie Name ="MHW" URL ="http://www.msn.com" > MHW=; path=/; domain=.msn.com; expires=Thu, 30-Oct-1980 16:00:00 GMT </ psf:browserCookie >
< psf:browserCookie Name ="MH" URL ="http://www.live.com" > MH=; path=/; domain=.live.com; expires=Wed, 30-Dec-2037 16:00:00 GMT </ psf:browserCookie >
< psf:browserCookie Name ="MHW" URL ="http://www.live.com" > MHW=; path=/; domain=.live.com; expires=Thu, 30-Oct-1980 16:00:00 GMT </ psf:browserCookie >
</ psf:browserCookies >
< psf:credProperties >
< psf:credProperty Name ="MainBrandID" />
< psf:credProperty Name ="BrandIDList" />
< psf:credProperty Name ="IsWinLiveUser" > true </ psf:credProperty >
< psf:credProperty Name ="CID" > 7b7c11618b2f2d9a </ psf:credProperty >
</ psf:credProperties >
< psf:extProperties >
< psf:extProperty Name ="LastUsedCredType" > 1 </ psf:extProperty >
</ psf:extProperties >
< psf:response />
</ psf:pp >
</ S:Header >
< S:Body >
< wst:RequestSecurityTokenResponseCollection xmlns:S ="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wst ="http://schemas.xmlsoap.org/ws/2004/04/trust" xmlns:wsse ="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu ="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml ="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp ="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:psf ="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault" >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:legacy </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > http://Passport.NET/tb </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-14T01:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< EncryptedData xmlns ="http://www.w3.org/2001/04/xmlenc#" Id ="BinaryDAToken0" Type ="http://www.w3.org/2001/04/xmlenc#Element" >
< EncryptionMethod Algorithm ="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
< ds:KeyInfo xmlns:ds ="http://www.w3.org/2000/09/xmldsig#" >
< ds:KeyName > http://Passport.NET/STS </ ds:KeyName >
</ ds:KeyInfo >
< CipherData >
< CipherValue > ATLrT3rRR8zHnGWNy4dPvrnLjY3xMFwEUc4LcPJQAsuPeYbft6mBs/V+P3iTpCbWfwyCO+OtZbt6RGyEKnmpOFuVXLBZ3atB02Rpu2xcK2+mkpnZC1Qso/T9Fe5kakO5qOVQj9IlBlElfxCvjP8Tg/Re0426i+pe2+tIWrjYuRpaUjpyaw/hc3/j01ZrHBfZz4zeTKs27gbFgug7foJ6hBxYzL5VpK9cyTsZyO+VRznRjGvo7/Sc9fEsSfgkuKZS9kIjfSOH9uIYCm//UDbzJfdcvnI+fsVzF/6ef7Icv9xT2KFLbfhGbhGaghjF9wYjZ6LAY+inun5F5yYnGYI13t52myKUQQ7phuO0QKG4RvhBv7BvuZ4MgYLClcLG2f0+0lN91MILxQ6cTxMz8XQy3pnB1w3PL2sCWQGhGBXMU9hYW97+V1XwujWGak73nqrWssJbe90= </ CipherValue >
</ CipherData >
</ EncryptedData >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport" />
< wsse:Reference URI ="#BinaryDAToken0" />
</ wst:RequestedTokenReference >
< wst:RequestedProofToken >
< wst:BinarySecret > WIU5wm+snSOlmofVFw0dhe/8/0RtPj3o </ wst:BinarySecret >
</ wst:RequestedProofToken >
</ wst:RequestSecurityTokenResponse >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:compact </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > messengerclear.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-13T09:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="Compact1" > t=EwBIAswbAQAUs1/VcBU2sH7mwYy3BysWZ71CRDGAAIfUuctsB2U2m79i4QxvkDMHYSWdJOP8LFJpjV9pD5klSgcVE8Z6dcJC5ebppv0j90QvWNwBAcrwLjvRTboV8DnRIGzrYHGkLcYwXiLEM4S1F6lT3pxup+/jU8Cd402e05dVKUE6/FQk/D73AKFBm5q6dMaql7XbN5cZxc/Kj6VxA2YAAAgc+RFTh2xYzJgBesaKCJnKus5wW9J6WppJ3SpGz4P6QZkaA+8r3e3CuQYCgXKuPCpnQdgeJlelZt4uXbCKDU/ln8F9cFbMYAKvgoCWOsu1QsHk43t59vkpsvQnwg2CS5ARkop2/iud4dFrXxkMVVXEjO2xZKNisefE9HT/MnVR/4+bwPtWmCsJ0p4HpYtYzMc4Zu2j33hR7nkM3x87K95eJ+HC1N0cFDFHpDmBBYdQ3oaR8Faxi2Yx6cfaWXM/uExdldcCCRbsuBk0a4cXO+xq2eypPPFnYs/T73m34enbvjJTPV532wLJ1z7JSYFEhHodmdxJhquHfPrz8eve+4tzjMqtNP0jy9Xk7G7+o1fcCt7u9k3pIydXbwFv3FFm9sP8lrNuQq6/8dOQpXIMQ0+LDd3OS3bWGqwAfvk6cak+xVB8trOpSFaijZpCNv6jnLsGDvIxSWUBXsRm3JooV8/SMFuJEUCDKVLw77FreVz5Yu8mtFpTn52a+iIxXRl8HKFc7Mmg+a3D5b441seyr2CsZHWuEuooa/bNJivSCOqS29hMogE= &p = </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport:compact" />
< wsse:Reference URI ="#Compact1" />
</ wst:RequestedTokenReference >
< wst:RequestedProofToken >
< wst:BinarySecret > nQxBa/vqQ7rC/4lCKemlPPGYwiIf5sQk </ wst:BinarySecret >
</ wst:RequestedProofToken >
</ wst:RequestSecurityTokenResponse >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:legacy </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > messenger.msn.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-13T01:49:48Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="PPToken2" > t=9f1kwMVt8HI11ZMGynBpTk9b8K0LpmcY3YqfiFkcHmDQJogbzZyWvsn9SZ7Rel0tgUiTosdUotoGaaXcOwXC4X4lci7jR0mK*DuS0ocFBPmaEXJTq8xUF5UGUiIiv7t46t &p =9DR5dce4tGhM6N5XZG6vKb8uxjswww8Esc*Y*JghIMSWI5!ZyBiBHhnatz1P7xzDaJmgx9tf3OuMmtr*t*btBrjTx2StrO0TvsnwZUon!CQhHlkYK2blKMXlhrof9O7mQ2ytdloWhXoq!KuRWXxgQoUZyWZjC0WYusIjaIvEUa*ZU$ </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport" />
< wsse:Reference URI ="#PPToken2" />
</ wst:RequestedTokenReference >
</ wst:RequestSecurityTokenResponse >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:compact </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > contacts.msn.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-13T09:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="Compact3" > t=EwDAAcBdAAAU7/9PdvvYJ23zPPtor/FYp6zOOb+AABUNAHBVIIifFj3qmqBZhJs0Bc3VWtLJoEBxH7T5+nW5TlsKToefZ0YgHEgaxE7gtCM0wTBBFjDA9df7H1jUx6V3QDDQFHByb6WkWSqrk99/TJ3+lMLeMB8SPaXES1ZHiqRTjnT4ta/fwvxoEw+ZTPO/o6HSOu9L91iP9tf1inahA2YAAAgmYvttWSQqCRABPQyikAvUy93r6eBUtapuOZu1O9YRmV1cqNV/1VTx6JdSom/3x32P/BgCZs8VjdQGpGaPhUiQs9HV8ufvmNfnk8xu+IEv8+N5P1xv2CWEceNPKJ/EhiAQEWB9y8i3yOVaywIegvEfqoE8xMDJPO5o43pIiS0xg0s8ntPdg6ATuVmdzS9NbrzZwWQXfXP1E2xJFJ4NqdPRXnhuCNdHavk+YPd7gVdrBPM1EF+A7zruzG/94euC0Sdw03400jt42Lh7YrqXjiY3NFVtc50mE30UOYIU9nZz7FAHmOZffX/QVN8HQixUZCG568fma51Pb1v3ZjYyMDW3CsDwh7eOQGBT3PoUpj6z8YIan2/cWCp2clciAQ== &p = </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport:compact" />
< wsse:Reference URI ="#Compact3" />
</ wst:RequestedTokenReference >
</ wst:RequestSecurityTokenResponse >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:compact </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > messengersecure.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-14T01:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="Compact4" > t=EwDAATIiAQAUno9QpucDnNi8T5syqJTstzjjm3WAAF0zVmkkTtjdJWEF16otckRaNSTfmPSJE6NA8LjA96t5kWvG/RxR9xG1X5SPIjftUMobZQq+Qilg/TQdEukbra5uYqgt2Gw37M6aopEe1zuqKcO6QtJuZJam08kohqLQfLNHoUabbVHE9mwyajhargs8hHz5JKNnUc/jd5kfbcmgA2YAAAi6PjAH1aqujRABCkmg56fEF6Ujl4p6VaZm/zx+C80C529UQDn1V7WqUySLsdhxWJDoy1G22WQlyV5/c1fan1d7EC+gV70/d77BA2bHleOLnrBQWyECfoah/XRIJRqJ5CVNvRaN2KFB5C/fTwgLulI6UBqcMgDm7O/V8xgH2JSsR2U+ps9tNiYcj0EpMSZFiNWIozXC211gOCfv+3s8/ZRJNKhTNWb9IyA/2e7tvmKHHqI0iALFsEQ7xgogKPiU1V8Zb1DBQBNK/ekEQ6hAXNPEF3606wcVrdomO+BStqEbDFVankTlEkikTgQoK+QPYZ2thyKeiQkgiGN4qnHi/a3CzKiM+IRQsZA/LjVqpj4G497aLQmvUZ9sTF4iAQ== &p = </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport:compact" />
< wsse:Reference URI ="#Compact4" />
</ wst:RequestedTokenReference >
</ wst:RequestSecurityTokenResponse >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:compact </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > spaces.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-13T09:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="Compact5" > t=EwDAARAnAAAURATre1Nkcu71L953y0QRAvwyKdOAANj6EddaH2UO/jVHlOjovb18yvn3KMHKs4zT8e9faKchYDlA1XPRaOxw2B93oqPwPJswZVRCY1IgBS3fTHd4HgasQGi89VVpl12lBwG5lgPPGE8NrS/frhOLScm2Py8q+oqzRSU40ZvHSQvoXQLWbktBq+brpJ/sCfnOInECG1qYA2YAAAg0lAeYfjrozhABxvngo2FVy1VCWecQcTHdPZMq2WGoz8csK89x2xUajaJ2+izlQNmBLg4/WyP11RsHY140ueqFLCnbcKt8NvwV+Y5U1iC0VtN4ky0tJQKUV0V1zG/VBIwCe7qbNGBxF1rrq+L9tC0blGbajPbkZVcAuAKQ7EmGQVVmbKeijZA/i2pYreMGXnHIUEB7wr8icdoeXTaoEwLsWH00S/rmA77BzC6v4CDUY8lw7wo1acTxn/9zsb8V7QYaafXSZILJ0lHQ1Hmz0aMxRRlQQAiXqFnlznhqNDu6I9NzJBm13ycxx5staZi7xjvrv8svCvGeX0Z++kVcaNwi1dNpmpX5Y+wCbATgGz5tah5SLQ44BBvr0zUiAQ== &p = </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport:compact" />
< wsse:Reference URI ="#Compact5" />
</ wst:RequestedTokenReference >
</ wst:RequestSecurityTokenResponse >
< wst:RequestSecurityTokenResponse >
< wst:TokenType > urn:passport:compact </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > storage.msn.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-13T09:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="Compact6" > t=EwDAAW+jAAAU7/9PdvvYJ23zPPtor/FYp6zOOb+AAOztl5rymSKrVexJAxpbKrIhqLKeglw+nhOvKDzoJbJBajlOpZ4PCHef0hQ4x3KWoE6Awz9abj3ACemcGwCLAEm7vnnQNjueDLzsomCIsdtZyiAWN6QAAjKavhQuDxEzPEF894au9lnvXJ53YAv9mZRFL4jRnql8U4wUEMS4M7oOA2YAAAioM9DwyzgDgBABiS/OhBKYEjw/S0Yx7Ygk/WDuVe+HTStTFl7996q06jnPueC7+F0DL6psv2QYukK4LpF/7XGkesXJAAHZDEuZdpkzOirXfe12mFnGYR7V82wjIMIj4cElhnt8+0w2/gl4LzHg/DpiETauqBQpC8r11JkcBy7UszfiLVm8JOykmSoHtxs8f8E3QsC3Lqv9guNRe+/7sol/rfkIgK86g/s0p1gKYYbUBi3nAVNINDrb3xUOBo7aqs/qw39/Z4A/2M4Bkq+SZAthjnygXcRNKJU2BXjRlIS76f1hupKUTJSGahN4KlpzHxGvr9BvTIc+ekND4s8BraTDt8zrWFe9Ee5eZ+tiunLcwV3/6nef2cMzhlsiAQ== &p = </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport:compact" />
< wsse:Reference URI ="#Compact6" />
</ wst:RequestedTokenReference >
</ wst:RequestSecurityTokenResponse >
</ wst:RequestSecurityTokenResponseCollection >
</ S:Body >
</ S:Envelope >
对应的,每一个RST都会返回一个这样的内容:
< wst:TokenType > urn:passport:compact </ wst:TokenType >
< wsp:AppliesTo xmlns:wsa ="http://schemas.xmlsoap.org/ws/2004/03/addressing" >
< wsa:EndpointReference >
< wsa:Address > messengerclear.live.com </ wsa:Address >
</ wsa:EndpointReference >
</ wsp:AppliesTo >
< wst:LifeTime >
< wsu:Created > 2007-09-13T01:41:28Z </ wsu:Created >
< wsu:Expires > 2007-09-13T09:41:28Z </ wsu:Expires >
</ wst:LifeTime >
< wst:RequestedSecurityToken >
< wsse:BinarySecurityToken Id ="Compact1" > t=EwBIAswbAQAU...= &p = </ wsse:BinarySecurityToken >
</ wst:RequestedSecurityToken >
< wst:RequestedTokenReference >
< wsse:KeyIdentifier ValueType ="urn:passport:compact" />
< wsse:Reference URI ="#Compact1" />
</ wst:RequestedTokenReference >
< wst:RequestedProofToken >
< wst:BinarySecret > nQxBa/vqQ7rC/4lCKemlPPGYwiIf5sQk </ wst:BinarySecret >
</ wst:RequestedProofToken >
</ wst:RequestSecurityTokenResponse >
其中的BinarySecurityToken就是这个服务的ticket了,就是"t="后面的那一串。我们要实现msn的登陆过程,则上面内容中的BinarySecret也是需要用到的。
好,现在我们已经获得登陆必需的ticket和BinarySecret了,可以连接NS服务器了。
通信过程如下
VER 4 MSNP15 CVR0
VER 4 MSNP15 CVR0
CVR 5 0x0804 winnt 5.1 i386 MSG80BETA 8.5.1238 msmsgs test@hotmail.com
CVR 5 8.1.0178 8.1.0178 8.1.0178
http://msgruser.dlservice.microsoft.com/download/B/D/3/BD343317-2DBF-48FE-8BD9-
9E3212D65E6A/Install_Messenger.exe http://get.live.com/cn
USR 6 SSO I test@hotmail.com
USR 6 SSO S MBI_KEY_OLD PKD3fof9V9uwVWrUxMEpi+Dki1oMkO1tpthPVEKjB7DGHwrkyBYzb6mOnU3EHlPi
GCF 0 69 <Policies>...</Policies>
USR 7 SSO S t=EwBIAswbAQAU...=&p= HAAAAAEAAAADZgAA...
USR 7 OK test@hotmail.com 1 0
SBS 0 null ...
BLP 8 BL
BLP 8 BL
ADL 9 67 <ml l="1">...</ml>
ADL 9 OK
PRP 10 MFN g
PRP 10 MFN g
CHL 0 29987175131175130567
QRY 12 PROD0118R6%2WYOS 32 4c6b96c27122919ae4a8d24a3015313d
QRY 12
在USR 6 SSO S 处获得服务器发送的Nonce,就是MBI_KEY_OLD后面的那一串;然后在USR 7 SSO S 处发
送认证的内容,包含了两部分,第一个t=...就是上面获得的ticket了,后面的那一串实际上是一个结
构体的内容,这个结构体由BinarySecret和获得的Nonce生成,具体的生成算法见http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO,我把代码也一块贴上吧:
... {
BYTE key1[24] = ...{0};
BYTE key2[24] = ...{0};
BYTE key3[24] = ...{0};
BYTE hash[20] = ...{0};
BYTE randomdata[8] = ...{0};
CString szRet ="";
DWORD dwBase64Size;
CryptStringToBinary(key,0,CRYPT_STRING_BASE64,0,&dwBase64Size,0,0);
ASSERT(dwBase64Size<=24);
if (dwBase64Size>24)
return "";
dwBase64Size = 24;
CryptStringToBinary(key,0,CRYPT_STRING_BASE64,key1,&dwBase64Size,0,0);
DeriveLoginKey(key1,24,"WS-SecureConversationSESSION KEY HASH",key2,24);
DeriveLoginKey(key1,24,"WS-SecureConversationSESSION KEY ENCRYPTION",key3,24);
HCRYPTPROV hProvider;
if ( !CryptAcquireContext(&hProvider,0,0,PROV_RSA_FULL,0) )
if(!CryptAcquireContext(&hProvider,0,0,PROV_RSA_FULL,CRYPT_NEWKEYSET))
return "";
...{
HCRYPTKEY hCryptKey;
HCRYPTKEY hCryptKey2;
BYTE * pImportKey = new BYTE[ 24+STDKEYHDRSIZE ];
memcpy(pImportKey,cKeyStdHeader,STDKEYHDRSIZE);
memcpy(pImportKey+STDKEYHDRSIZE,key2,24);
CryptImportKey(hProvider,pImportKey,24+STDKEYHDRSIZE,0,CRYPT_SF,&hCryptKey2);
memcpy(pImportKey+STDKEYHDRSIZE,key3,24);
if ( CryptImportKey(hProvider,pImportKey,24+STDKEYHDRSIZE,0,CRYPT_SF,&hCryptKey) )
...{
HCRYPTKEY hKeyDupe1;
HCRYPTKEY hKeyDupe2;
HCRYPTHASH hHash;
CryptDuplicateKey(hCryptKey,0,0,&hKeyDupe1);
DWORD dwMode = CRYPT_MODE_CBC;
CryptSetKeyParam(hKeyDupe1,KP_MODE,(BYTE*)&dwMode,0);
if (CryptCreateHash(hProvider,CALG_HMAC,hCryptKey2,0,&hHash))
...{
HMAC_INFO hmcinfo;
ZeroMemory(&hmcinfo, sizeof(HMAC_INFO));
hmcinfo.HashAlgid = CALG_SHA1;
CryptSetHashParam(hHash,HP_HMAC_INFO,(BYTE*)&hmcinfo,0);
DWORD dwDataLen = challenge.GetLength();
CryptDuplicateKey(hKeyDupe1,0,0,&hKeyDupe2);
CryptEncrypt(hKeyDupe2,0,TRUE,0,0,&dwDataLen,0);
CryptDestroyKey(hKeyDupe2);
if ( dwDataLen > 0)
...{
CryptGenRandom(hProvider,8,randomdata);
CryptSetKeyParam(hKeyDupe1,KP_IV,randomdata,0);
BYTE * pEncryptBytes = new BYTE[dwDataLen];
ZeroMemory(pEncryptBytes,dwDataLen);
memcpy(pEncryptBytes,(LPCSTR)(LPCTSTR)challenge,challenge.GetLength());
DWORD dwData = challenge.GetLength();
if (CryptEncrypt(hKeyDupe1,hHash,TRUE,0,pEncryptBytes,&dwData,dwDataLen))
...{
ASSERT(dwData == 72); // The size of the encryption *should* always be 72. If it's not you'll need to fix it.
dwData = 20;
CryptGetHashParam(hHash,HP_HASHVAL,hash,&dwData,0);
MSGUSRKEY usrkey;
memcpy(usrkey.aIVBytes, randomdata,8);
memcpy(usrkey.aHashBytes, hash,20);
memcpy(usrkey.aCipherBytes , pEncryptBytes,72);
CryptBinaryToString((BYTE*)&usrkey,sizeof(MSGUSRKEY),CRYPT_STRING_BASE64, 0,&dwBase64Size);
CryptBinaryToString((BYTE*)&usrkey,sizeof(MSGUSRKEY),CRYPT_STRING_BASE64, szRet.GetBuffer(dwBase64Size),&dwBase64Size);
szRet.ReleaseBuffer();
szRet.Replace(" ","");
}
delete[] pEncryptBytes;
}
CryptDestroyHash(hHash);
}
CryptDestroyKey(hKeyDupe1);
CryptDestroyKey(hCryptKey);
}
delete[] pImportKey;
if ( hCryptKey2 )
CryptDestroyKey(hCryptKey2);
CryptReleaseContext(hProvider,0);
}
return szRet;
}
好了,当服务器回应USR 7 OK时,就登陆上去了。ADL是发送联系人列表,这个列表是通过https方式从contacts.msn.com服务器得到的,这个过程同样也需要对应的ticket,这里就不详述了。(msn只在第一次登陆时从服务器上获取列表,以后就直接从本地的加密文件中读取。)
登陆成功以后,服务器会发送一个验证请求,就是CHL命令,带了一串challenge,需要我们回应正确的验证值。验证值由challenge、PRODUCT_KEY和PRODUCT_ID生成,其中PRODUCT_KEY和PRODUCT_ID是两个固定的字符串,不同版本的msn有着不同的key和id,比如我们现在模拟的这个版本就分别是:
PRODUCT_KEY:YIXPX@5I2P0UT*LK
PRODUCT_ID:PROD0118R6%2WYOS
验证值生成如下:
... {
char *productKey = MSN_PRODUCT_KEY,
*productID = MSN_PRODUCT_ID,
*hexChars = "0123456789abcdef",
buf[BUFSIZE];
unsigned char md5Hash[16], *newHash;
unsigned int *md5Parts, *chlStringParts, newHashParts[5];
LONG64 nHigh=0, nLow=0;
int i, bigEndian;
/**//* Determine our endianess */
bigEndian = isBigEndian();
/**//* Create the MD5 hash */
_snprintf(buf, BUFSIZE-1, "%s%s", input, productKey);
MD5((unsigned char *)buf, strlen(buf), md5Hash);
/**//* Split it into four integers */
md5Parts = (unsigned int *)md5Hash;
for(i=0; i<4; i++)
...{
/**//* check for endianess */
if(bigEndian)
md5Parts[i] = swapInt(md5Parts[i]);
/**//* & each integer with 0x7FFFFFFF */
/**//* and save one unmodified array for later */
newHashParts[i] = md5Parts[i];
md5Parts[i] &= 0x7FFFFFFF;
}
/**//* make a new string and pad with '0' */
_snprintf(buf, BUFSIZE-5, "%s%s", input, productID);
i = strlen(buf);
memset(&buf[i], '0', 8 - (i % 8));
buf[i + (8 - (i % 8))]='/0';
chlStringParts = (unsigned int *)buf;
/* this is magic */
for (i=0; i<(strlen(buf)/4)-1; i+=2)
{
LONG64 temp;
if(bigEndian)
{
chlStringParts[i] = swapInt(chlStringParts[i]);
chlStringParts[i+1] = swapInt(chlStringParts[i+1]);
}
temp=(md5Parts[0] * (((0x0E79A9C1 * (LONG64)chlStringParts[i]) % 0x7FFFFFFF)+nHigh) + md5Parts[1])%0x7FFFFFFF;
nHigh=(md5Parts[2] * (((LONG64)chlStringParts[i+1]+temp) % 0x7FFFFFFF) + md5Parts[3]) % 0x7FFFFFFF;
nLow=nLow + nHigh + temp;
}
nHigh=(nHigh+md5Parts[1]) % 0x7FFFFFFF;
nLow=(nLow+md5Parts[3]) % 0x7FFFFFFF;
newHashParts[0]^=nHigh;
newHashParts[1]^=nLow;
newHashParts[2]^=nHigh;
newHashParts[3]^=nLow;
/* swap more bytes if big endian */
for(i=0; i<4 && bigEndian; i++)
newHashParts[i] = swapInt(newHashParts[i]);
/* make a string of the parts */
newHash = (unsigned char *)newHashParts;
/* convert to hexadecimal */
for (i=0; i<16; i++)
{
output[i*2]=hexChars[(newHash[i]>>4)&0xF];
output[(i*2)+1]=hexChars[newHash[i]&0xF];
}
output[32]='/0';
return 0;
}
如上向服务器发回验证值,服务器回复QRY则说明通过验证,否则会断开连接。至此登陆验证过程完毕。