[转载]C#模拟百度登录并到指定网站评论回帖(三) - 断言鸟 - 博客园

来源: [转载]C#模拟百度登录并到指定网站评论回帖(三) – 断言鸟 – 博客园

上次说到怎么获取BAIDUID,这个相信很多人都能够拿到就不多说了,今天一连说两个,获取token和raskey

  2、利用以上获得的cookie直接访问页面
https://passport.baidu.com/v2/api/?getapi&tpl=zongheng&apiver=v3&tt=1441287460704&class=login&gid=26D2A76-9D6C-4EBE-8687-25C6591194B2&logintype=basicLogin&callback=bd__cbs__v9tdyy获取参数token
在第一篇文章中写到这个,拿着我们储存到的BAIDUID直接请求这个页面,就能够获取到反馈回来的Json格式的数据
这里的话需要用到一个dll,添加引用到项目【Newtonsoft.Json】
至于这个文档怎么用,已经有其他前辈的博文中说到,我这里就不解释了,如果不懂的可以在后面看代码
如果你拿不到token,那么只有一个问题,你没有BAIDUID,如果你确认第一次是收集到了,那么请重复检验在请求token时这个Cookies是否还存在。(很多时候是Cookies的效期问题导致Cookies收集器将失效的BAIDUID自动丢弃)
  有了前面的步骤,拿到raskey也就很简单了,步骤是一样的,将前面所有的Cookies都保存下来,接下来
  3、用token访问该地址,获取raskeyhttps://passport.baidu.com/v2/getpublickey?token=5d0fc87cb0de39982c06795d3356e239&tpl=zongheng&apiver=v3&tt=1441311621601&gid=59723A6-1178-4614-B7AF-779917BC4453&callback=bd__cbs__gaci47和publickey,注意将地址中的值替换。
  很明显,你会发现反馈回来的也是一个Json数据,但可以看到后面有一串以—–BEGIN PUBLIC KEY—– 开头以—-End Public KEY—-结尾的数据,那里面就是publickey,而紧跟在后的key后的字符串就是raskey,用上面同样的办法拿到这两组数据,切记前一组要将开头和结尾的标识字符串也要截取出来,而不是单纯的乱字符串。
  现在算一下我们拿到的东西:3个页面的Cookies、token、publickey、raskey
      这几个都齐全了,那么就可以向百度提交post请求登录,但在这之前,你需要准备一串经过ras加密过后的密码,否则会一直提示密码错误,也就是err_7。
      这块需要添加另外一个引用【BouncyCastle.Crypto.dll】这是哪个大神写的就不清楚了,但非常实用,很感谢这些大神做出的贡献。之后添加一个类:
</div>
<div>
<div>Newtonsoft.Json.Net35.dll(Josn数据解析)</div>
<div>BouncyCastle.Crypto.dll</div>
<div>using System;</div>
<div>using System.IO;</div>
<div>using System.Security.Cryptography;</div>
<div>using System.Text;</div>
<div>using Org.BouncyCastle.Crypto;</div>
<div>using Org.BouncyCastle.Crypto.Parameters;</div>
<div>using Org.BouncyCastle.OpenSsl;</div>
<div>using Org.BouncyCastle.Security;</div>
<div></div>
<div>namespace 纵横小说自动评论</div>
<div>{</div>
<div>    /// &lt;summary&gt;</div>
<div>    /// rsakey密码加密帮助</div>
<div>    /// &lt;/summary&gt;</div>
<div>   public class RsaHelper</div>
<div>    {</div>
<div>        public static string PemToXml(string pem)</div>
<div>        {</div>
<div>            if (pem.StartsWith("-----BEGIN RSA PRIVATE KEY-----")</div>
<div>                || pem.StartsWith("-----BEGIN PRIVATE KEY-----"))</div>
<div>            {</div>
<div>                return GetXmlRsaKey(pem, obj =&gt;</div>
<div>                {</div>
<div>                    if ((obj as RsaPrivateCrtKeyParameters) != null)</div>
<div>                        return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)obj);</div>
<div>                    var keyPair = (AsymmetricCipherKeyPair)obj;</div>
<div>                    return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private);</div>
<div>                }, rsa =&gt; rsa.ToXmlString(true));</div>
<div>            }</div>
<div></div>
<div>            if (pem.StartsWith("-----BEGIN PUBLIC KEY-----"))</div>
<div>            {</div>
<div>                return GetXmlRsaKey(pem, obj =&gt;</div>
<div>                {</div>
<div>                    var publicKey = (RsaKeyParameters)obj;</div>
<div>                    return DotNetUtilities.ToRSA(publicKey);</div>
<div>                }, rsa =&gt; rsa.ToXmlString(false));</div>
<div>            }</div>
<div></div>
<div>            throw new InvalidKeyException("Unsupported PEM format...");</div>
<div>        }</div>
<div>        private static string GetXmlRsaKey(string pem, Func&lt;object, RSA&gt; getRsa, Func&lt;RSA, string&gt; getKey)</div>
<div>        {</div>
<div>            using (var ms = new MemoryStream())</div>
<div>            using (var sw = new StreamWriter(ms))</div>
<div>            using (var sr = new StreamReader(ms))</div>
<div>            {</div>
<div>                sw.Write(pem);</div>
<div>                sw.Flush();</div>
<div>                ms.Position = 0;</div>
<div>                var pr = new PemReader(sr);</div>
<div>                object keyPair = pr.ReadObject();</div>
<div>                using (RSA rsa = getRsa(keyPair))</div>
<div>                {</div>
<div>                    var xml = getKey(rsa);</div>
<div>                    return xml;</div>
<div>                }</div>
<div>            }</div>
<div>        }</div>
<div></div>
<div></div>
<div>        /// &lt;summary&gt;</div>
<div>        /// RSA加密</div>
<div>        /// &lt;/summary&gt;</div>
<div>        /// &lt;param name="publickey"&gt;&lt;/param&gt;</div>
<div>        /// &lt;param name="content"&gt;&lt;/param&gt;</div>
<div>        /// &lt;returns&gt;&lt;/returns&gt;</div>
<div>        public static string RSAEncrypt(string publickey, string content)</div>
<div>        {</div>
<div>            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();</div>
<div>            byte[] cipherbytes;</div>
<div>            rsa.FromXmlString(publickey);</div>
<div>            cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);</div>
<div></div>
<div>            return Convert.ToBase64String(cipherbytes);</div>
<div>        }</div>
<div></div>
<div>        /// &lt;summary&gt;</div>
<div>        /// RSA解密</div>
<div>        /// &lt;/summary&gt;</div>
<div>        /// &lt;param name="privatekey"&gt;&lt;/param&gt;</div>
<div>        /// &lt;param name="content"&gt;&lt;/param&gt;</div>
<div>        /// &lt;returns&gt;&lt;/returns&gt;</div>
<div>        public static string RSADecrypt(string privatekey, string content)</div>
<div>        {</div>
<div>            privatekey =</div>
<div>                @"&lt;RSAKeyValue&gt;&lt;Modulus&gt;5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;P&gt;/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==&lt;/P&gt;&lt;Q&gt;6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==&lt;/Q&gt;&lt;DP&gt;ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==&lt;/DP&gt;&lt;DQ&gt;MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==&lt;/DQ&gt;&lt;InverseQ&gt;EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==&lt;/InverseQ&gt;&lt;D&gt;vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=&lt;/D&gt;&lt;/RSAKeyValue&gt;";</div>
<div>            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();</div>
<div>            byte[] cipherbytes;</div>
<div>            rsa.FromXmlString(privatekey);</div>
<div>            cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);</div>
<div></div>
<div>            return Encoding.UTF8.GetString(cipherbytes);</div>
<div>        }</div>
<div>    }</div>
<div>}</div>
<div>
好了,用这个类将密码加密后就Post所有数据吧,下面是具体实现代码
</div>
<div> //获取token
private Regex _regex = new Regex(@"\{.*\}", RegexOptions.IgnoreCase);
/// &lt;summary&gt;
/// 根据BAIDUID获取token
/// &lt;/summary&gt;
public string GetToken()
{
HttpCookie cookie = new HttpCookie("BDRCVFR[gltLrB7qNCt]");
cookie.Value = "mk3SLVN4HKm";
cookie.Expires = DateTime.Now.AddDays(1);
string url_getToken = string.Format("<a href="https://passport.baidu.com/v2/api/?getapi&amp;tpl=zongheng&amp;apiver=v3&amp;tt=">https://passport.baidu.com/v2/api/?getapi&amp;tpl=zongheng&amp;apiver=v3&amp;tt=</a>{0}&amp;class=login&amp;gid=0743012-DD22-4632-B84E-B054B933DDA0&amp;logintype=basicLogin&amp;callback=bd__cbs__xjugf7", Utility.GetTimeStamp());
string token_get = helper.GetPageResponse_Get(url_getToken, Utility.UrlDecode("<a href="http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F">http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F</a>"), "*/*");
if (_regex.IsMatch(token_get))
token_get = _regex.Match(token_get).Value;
var resultToken = JsonConvert.DeserializeObject&lt;ResultToken&gt;(token_get);
if (string.IsNullOrEmpty(resultToken.Data.Token))
{
ShowLog("Parameter-:获取token=" + resultToken.Data.Token + "失败\n");
return null;
}
return resultToken.Data.Token;
}
//获取raskey
public string GetRasKey(string token)
{
string url_RasKey = string.Format("<a href="https://passport.baidu.com/v2/getpublickey?token=">https://passport.baidu.com/v2/getpublickey?token=</a>{0}&amp;tpl=zongheng&amp;apiver=v3&amp;tt={1}&amp;gid=399423B-A0F5-42A0-B07F-CC5290F8F95D&amp;callback=bd__cbs__xjugf7", token, Utility.GetTimeStamp());
string publicKey = helper.GetPageResponse_Get(url_RasKey, Utility.UrlDecode("<a href="http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F">http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F</a>"), "*/*");
//获取raskey
if (_regex.IsMatch(publicKey))
publicKey = _regex.Match(publicKey).Value;
var result_publicKey = JsonConvert.DeserializeObject&lt;PublicRsaKey&gt;(publicKey);
var rsakey = result_publicKey.Key;
//将密码加密
var pemToXml = RsaHelper.PemToXml(result_publicKey.Pubkey);
pwd = RsaHelper.RSAEncrypt(pemToXml, pwd);
//日志
if (!string.IsNullOrEmpty(rsakey))
return rsakey;
ShowLog("Parameter-:获取publickey=" + result_publicKey.Pubkey + "失败!");
ShowLog("Parameter-:获取raskey=" + rsakey + "失败!");
return null;
}/// &lt;summary&gt;
/// 登录实现
/// &lt;/summary&gt;
public LoginStatus Login(string verifycode, string codestring, string token, string raskey, int userIndex)
{
string loginresult = "";
string url_Post = "<a href="https://passport.baidu.com/v2/api/?login">https://passport.baidu.com/v2/api/?login</a>";
long tt= Utility.GetTimeStamp();
string postData = string.Format("verifycode={0}&amp;username={1}&amp;u=<a href="http://zongheng.baidu.com/sendbduss.do?source=0&amp;location=http%3A%2F%2Fwww.zongheng.com%2F&amp;_t=">http://zongheng.baidu.com/sendbduss.do?source=0&amp;location=http%3A%2F%2Fwww.zongheng.com%2F&amp;_t=</a>{2}&amp;tt={3}&amp;tpl=zongheng&amp;token={4}&amp;staticpage=<a href="http://passport.zongheng.com/v3Jump.html&amp;safeflg=0&amp;rsakey=">http://passport.zongheng.com/v3Jump.html&amp;safeflg=0&amp;rsakey=</a>{5}&amp;quick_user=0&amp;ppui_logintime=20266&amp;password={6}&amp;mem_pass=on&amp;logLoginType=pc_loginBasic&amp;logintype=basicLogin&amp;loginmerge=true&amp;isPhone=false&amp;gid=0743012-DD22-4632-B84E-B054B933DDA0&amp;detect=1&amp;crypttype=12&amp;codestring={7}&amp;charset=utf-8&amp;callback=parent.bd__pcbs__ok0875&amp;apiver=v3", verifycode, HttpUtility.UrlEncode(userName), tt,tt, HttpUtility.UrlEncode(token), HttpUtility.UrlEncode(raskey), HttpUtility.UrlEncode(pwd), codestring);
loginresult =helper.GetPageResponse_Post(url_Post, postData, Utility.UrlDecode("<a href="http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F">http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F</a>"));
//分析loginresult
string err = @"(?&lt;=err_no=)[^&amp;]+?(?=&amp;)";
Match regx = Regex.Match(loginresult, err);
string codestr = "(?&lt;=codeString=)[^&amp;]+?(?=&amp;)";
string codetype = "(?&lt;=vcodetype=)[^&amp;]+?(?=&amp;)";
Match regx2 = Regex.Match(loginresult, codestr);
Match regx3 = Regex.Match(loginresult, codetype);
string errno = regx.Value;
_codestring = regx2.Value;
vcodeType= regx3.Value;
//根据返回的错误号提示信息,并且请求验证码
switch (errno)
{
case "257":
return LoginStatus.codeGet;
case "7": ShowLog("账号或密码错误...");
ChangeStauts("失败", userIndex);
return LoginStatus.loginFail;;
case "0": ShowLog("登录成功...");
ChangeStauts("成功", userIndex);
break;
default: ShowLog("未知错误...");
ChangeStauts("错误", userIndex);
return LoginStatus.Error;;
}
return LoginStatus.loginSucceed;
}</div>
<div>
今天就到这里,明天说说验证码的问题,不过很大部分情况下,除非你的密码几次输入错误或者异地登录,不然一般不会让你输入验证码,如有问题欢迎评论交流
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏