C# 實現對接電信交費易自動繳費


先把電信的交費易上個圖,有手機版的和網頁版

網頁版的地址: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}&poundage={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/

請不要刪除些引用地址

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM