先把电信的交费易上个图,有手机版的和网页版
网页版的地址:http://b.bestpay.com.cn
手机版的我上个图吧,你也可以到上面网页版中下载安装
我主要是使用网页版来实现其功能,打开官网如下
OK,好了,现在我们开始我们的工作,
第一步当然是模拟登陆进去了,通过抓包工作,我们可以得到如下图的数据
这几个参数除了password 我相信大家都能看明白, 这个 password 其实就是那个安全插件加密得到,具体怎么得到,见下面
他有这样一个JS PassGuardCtrl.js 部分代码
1 defaults:{ 2 obj:null, 3 random:null,//随机因子数 4 hidPwdName:'password',//隐藏密码框名字,用来保存加密后的密码值 5 outInputClass:'',//要把密码输入框写到的位置 6 params:{//附加属性,可选 7 pgePath: "./ocx/",//控件文件目录 8 pgeId: "_ocx_password",//控件ID 9 pgeEdittype: 0,//控件类型,0星号,1明文 10 pgeEreg1: "[\\s\\S]*",//输入过程中字符类型限制 11 pgeEreg2: "[\\s\\S]{6,50}", //输入完毕后字符类型判断条件 12 pgeMaxlength: 50,//允许最大输入长度 13 pgeTabindex: 2,//tab键顺序 14 pgeClass: "ocx_style",//控件css样式 15 pgeInstallClass: "ocx_style",//针对安装或升级 16 pgeOnkeydown:"FormSubmit()",//回车键响应函数 17 tabCallback:"_ocx_password2" 18 }
这段 js 就是对密码控件初始化.后台我在后面会把它改成 C#的
_setRandom:function(){ if(null==this.settings.random){ alert("error:random is empty"); return false; } this.object.pwdSetSk(this.settings.random); return true; } }
pwdSetSk: function(s) { if (this.checkInstall()) { try { var control = document.getElementById(this.settings.pgeId); if (this.osBrowser==1 || this.osBrowser==3 || this.osBrowser==6 || this.osBrowser==8) { control.input1=s; } else if (this.osBrowser==2 || this.osBrowser==4 || this.osBrowser==5) { control.input(1,s); } } catch (err) { } }
这个js文件是设置安全控件的 随机因子 操作的是 安全控件的 input1
pwdResult: function() { var code = ''; if (!this.checkInstall()) { code = ''; } else{ try { var control = document.getElementById(this.settings.pgeId); if (this.osBrowser==1 || this.osBrowser==3) { code = control.output1; } else if (this.osBrowser==2 || this.osBrowser==4 || this.osBrowser==5) { code = control.output(7); }else if (this.osBrowser==6 || this.osBrowser==8) { code = control.get_output1(); } } catch (err) { code = ''; } } //alert(code); return code; },
这个文件是我们的主角,就是当我们在安全控件中输入内容后,自动的将我们的密码加密.但是加出的密码并不是提交的那个密文,还要进行一次 BASE64加密
function setPwdVal(clazz){ var _$=jQuery; _$("input."+clazz).each(function(i,n){ var _objId = _$(n).attr("objId"); var _code = null; var control = _$("#"+_objId)[0]; _code=window["PassGuardCtrl"+control.id.split("-")[0].toLocaleLowerCase()].pwdResult(); //_code = Base64.encoder(_code); _code=BASE64.encoder(_code); _$(n).val(_code); }); }
在这这个方法中可以看到,使用了一次 BASE64加密,
经过上面这几个步骤后.可以将我们的密码加密成和提交时候的一样,
VS中添加安全控件, 大家可能都用过,基本的是 首先在工具栏右键->选择项->COM组件->选择对应的组件,OK了
但是很不幸 当你把控件拖入到界面上的时候,你的VS就崩了,我用vs2005,vs2008 vs2010 vs2013 都崩没找到好的办法,只能自己手动来创建,这个估计要点功点了.
我估计这是控件的安全性引起VS崩溃的吧,以前做支机支付辅助也一样VS也会崩,发现这个控件其实是同一个,只是只不同的名称,(应该是 电信和移动的项目外包到同一家公司了,呵呵)
现在把密码和加密码方式的核心代码段贴上,
public static String GetPayPass(AxPassGuardCtrlLib.AxPassGuard paypwd, String random) {
paypwd.input1 = random;
paypwd.edittype = 0;
paypwd.maxlength = 50;
paypwd.input2 = "[\\s\\S]*";//输入过程中字符类型限制
paypwd.input13 = "[\\s\\S]{6,50}";
String strPwd = paypwd.output1;
paypwd.ClearSeCtrl();
return EncodeBase64(strPwd);
}
这个random 随机因子大你登陆的那个页上可以找到
注意哦,这个并不是不变的,每次好像都是不一样的当你刷新页面的时候,所有我们要登陆首页先请求下登陆面把这个随机因子获取出来
下面是我的登陆部分方法.
internal void Login() { String Result = ""; net.Url = "https://b.bestpay.com.cn/bppf/login.do?method=login"; net.Method = NetHelper.RequestMethod.GET; net.IsStream = false; Result = net.SendRequest(); if (Result.StartsWith("-1")) { LastError = "无法连接服务器"; return; } String random = Utils.GetValue(Result, "pwdSetSk\\(\"", "\""); Utils.SetPassword(PassGuard, LoginPass); net.Url = "https://b.bestpay.com.cn/bppf/vimage.do?0." + Utils.GetUnixTime(); net.Referer = "https://b.bestpay.com.cn/bppf/login.do?method=login"; net.IsStream = true; net.Method = NetHelper.RequestMethod.GET; net.SendRequest(); if (net.IOStream == null) { LastError = "获取验证码失败"; return; } Bitmap bmp = new Bitmap(net.IOStream); String chkCode = Captcha.GetCheckString(bmp); //检测验证码 net.Url = "https://b.bestpay.com.cn/bppf/verifyCode"; net.PostData = "verifyCode=" + chkCode; net.IsStream = false; net.Method = NetHelper.RequestMethod.POST; Result = net.SendRequest(); if (Result.StartsWith("-1") || Result != "true") { LastError = "无法连接服务器"; return; } String LoginPwd = Utils.GetPayPass(PassGuard, random); net.Url = "https://b.bestpay.com.cn/bppf/login.do"; net.PostData = "signature=&certSN=&toURL=&TOURL_MENUID=&sysLoginType=BPPF&username=" + MerchantId + "&password=" + LoginPwd + "&method=login&verifyCode=" + chkCode; net.Method = NetHelper.RequestMethod.POST; net.Encode = "gbk"; net.IsStream = false; Result = net.SendRequest(); LastError = Result; if (Result.Contains("商户ID:" + MerchantId)) { IsLogin = true; dAmt0 = Convert.ToDecimal(Utils.GetValue(Result, "账户余额:<span class=\"property-amount\">", "</span>")); dAmt1 = Convert.ToDecimal(Utils.GetValue(Result, "可用余额:<span class=\"property-amount\">", "</span>")); dAmt2 = Convert.ToDecimal(Utils.GetValue(Result, "酬金余额:<span class=\"property-amount\">", "</span>")); dAmt3 = Convert.ToDecimal(Utils.GetValue(Result, "冻结金额:<span class=\"property-amount\">", "</span>")); } }
手机充值下单方法
internal Boolean MobilePay(Order order, ref String msg) { Boolean isSuccess = false; for (int i = 0; i < 3; i++) { String Result = ""; net.Url = "https://b.bestpay.com.cn/bppf/ipos/mobilerecharge.do?method=process"; net.Method = NetHelper.RequestMethod.POST; net.PostData = "mobile=" + order.Account + "&otherMoney=" + order.Price + "&moneyText="; net.IsStream = false; Result = net.SendRequest(); if (Result.StartsWith("-1")) { continue; } if (!Result.Contains("请您核对好运营商信息、充值号码和金额,避免充错")) { continue; } String random = Utils.GetValue(Result, "pwdSetSk\\(\"", "\""); String token = Utils.GetValue(Result, "\"org.apache\\.struts\\.taglib\\.html\\.TOKEN\"", "type"); token = Utils.GetValue(Result, "value=\"", "\"").Trim(); String phone = Utils.GetValue(Result, "name=\"phone\" value=\"", "\"").Trim(); String money = Utils.GetValue(Result, "name=\"money\" value=\"", "\"").Trim(); String txnAmount = Utils.GetValue(Result, "name=\"txnAmount\" value=\"", "\"").Trim(); String poundage = Utils.GetValue(Result, "name=\"poundage\" value=\"", "\"").Trim(); Utils.SetPassword(PassGuard, PayPass); if (order.Account != phone) { msg = "充值帐号袚篡改"; return false; } if (order.Price != money) { msg = "充值金额袚篡改"; return false; } String PayPwd = Utils.GetPayPass(PassGuard, random); net.Url = "https://b.bestpay.com.cn/bppf/ipos/mobilerecharge.do?method=checkPayPwd&payPwd=" + PayPwd; net.Method = NetHelper.RequestMethod.POST; net.PostData = ""; net.IsStream = false; Result = net.SendRequest(); Log.Write(Result, "debut.txt"); net.Url = "https://b.bestpay.com.cn/bppf/ipos/mobilerecharge.do?method=confirm"; net.Method = NetHelper.RequestMethod.POST; net.PostData = String.Format("org.apache.struts.taglib.html.TOKEN={0}&phone={1}&money={2}&txnAmount={3}£age={4}&receivePhone={5}&payPwd={6}", token, phone, money, txnAmount, poundage, phone, PayPwd); Log.Write(net.PostData,"debug.txt"); net.IsStream = false; Result = net.SendRequest(); if(Result.Contains("充值成功")){ msg = "缴费下单成功"; return true; } msg = Utils.GetValue(Result, "充值失败原因:</span><span class=\"title\" style=\"color: red;\">", "</span>"); Log.Write(Result, "debut.txt"); } return isSuccess; }
内容已经实现在太长了,没办法继续了,下一篇来讲一下,C#+(winio/winring0) 实现对其安全控件的自动填充密码,上面的在测试时候,大家可以先手动的在控件中输入密码.
先到这里吧,上一个完整的软件效果图
--幸福海
博客地址:http://www.cnblogs.com/ningqhai/
请不要删除些引用地址