目錄:
1、fiddler解析百度登錄地址
2、處理傳入參數
因工作需要,所以研究了下百度的登陸。首先打開https://passport.baidu.com/v2/?login,我們用fiddler很快就能找到百度的登錄入口https://passport.baidu.com/v2/api/?login .如下圖:

在登錄入口https://passport.baidu.com/v2/api/?login 之前,百度先會去獲取publickey和token。token是服務器和客戶端關聯的唯一id。publickey是一個rsa(非對稱加密)用來加密輸入的密碼的。所以要模擬登錄。必須要拿到這兩個參數。
通過fildder我們很快拿到了獲取token和publickey的地址。
token(https://passport.baidu.com/v2/api/?getapi&tpl=pp&apiver=v3&tt=1433836782422&class=login&logintype=basicLogin&callback=bd__cbs__7fwpot)
publickey(https://passport.baidu.com/v2/api/?loginhistory&token=414cf195652963982d479ecf0cee814b&tpl=pp&apiver=v3&tt=1433836782658&callback=bd__cbs__57q1jk)
可以看出先拿到token,然後用這個token再去拿publickey。如下圖:

這兩個都拿到了。
注意:我們看到返回的pubkey是以 -----BEGIN PUBLIC KEY----- 開始 和-----END PUBLIC KEY----- 結束的。這是pem格式。我們要轉換成xml格式的。因為.net平台自帶的RSACryptoServiceProvider解析的是xml字符串。所以有了下面的幫助類:
需要引用:BouncyCastle.Crypto.dll
public class RSAHelper
{
public static string PemToXml(string pem)
{
if (pem.StartsWith("-----BEGIN RSA PRIVATE KEY-----")
|| pem.StartsWith("-----BEGIN PRIVATE KEY-----"))
{
return GetXmlRsaKey(pem, obj =>
{
if ((obj as RsaPrivateCrtKeyParameters) != null)
return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)obj);
var keyPair = (AsymmetricCipherKeyPair)obj;
return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private);
}, rsa => rsa.ToXmlString(true));
}
if (pem.StartsWith("-----BEGIN PUBLIC KEY-----"))
{
return GetXmlRsaKey(pem, obj =>
{
var publicKey = (RsaKeyParameters)obj;
return DotNetUtilities.ToRSA(publicKey);
}, rsa => rsa.ToXmlString(false));
}
throw new InvalidKeyException("Unsupported PEM format...");
}
private static string GetXmlRsaKey(string pem, Func<object, RSA> getRsa, Func<RSA, string> getKey)
{
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(ms))
using (var sr = new StreamReader(ms))
{
sw.Write(pem);
sw.Flush();
ms.Position = 0;
var pr = new PemReader(sr);
object keyPair = pr.ReadObject();
using (RSA rsa = getRsa(keyPair))
{
var xml = getKey(rsa);
return xml;
}
}
}
/// <summary>
/// RSA加密
/// </summary>
/// <param name="publickey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSAEncrypt(string publickey, string content)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(publickey);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
return Convert.ToBase64String(cipherbytes);
}
/// <summary>
/// RSA解密
/// </summary>
/// <param name="privatekey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSADecrypt(string privatekey, string content)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(privatekey);
cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);
return Encoding.UTF8.GetString(cipherbytes);
}
}
下面就可以用HttpWebRequest開始模擬登錄了。當cookies中包含 BAIDUID 則說明登錄成功。還有就是訪問https://passport.baidu.com/v2/api/?login,返回的字符串中 err_no=0 表示登錄成功了。
附件:
demo