在线支付平台(大多数)采用的加密方法之MD5
2008-12-26 16:35 Kevin Zhou 阅读(4061) 评论(39) 编辑 收藏 举报现在的网络安全确实不是令人很放心,那么作为“在线支付”的一些直接和RMB打交道的系统,安全性的要求就更高了,那么一般我们会采用什么样的方式来保证各个系统间(比如A方系统和支付宝等一些在线支付系统)参数传递的正确性、严密性?
闲话不多说,根据我在支付部门长期的工作经验,以及接触到的各种支付接口,总结来看,加密参数无非采用证书、md5等方法,下面谈一下md5加密方法:
假设以下是双方参数约定,由网上商城A(假设为shop)提交支付参数到银行B(假设为bank)进行支付,双方约定:
Shop提交到bank的参数为
参数名 | 类型 | 长度 | 可空 | 说明 |
Order_no | string | 50 | Not null | 订单号 |
money | double | 16 | Not null | 金额 |
Order_date | string | 14 | Not null | 订单日期 |
Validate_Key | string | 100 | Not null | 加密后的字符串 |
支付成功后,bank返回shop的参数为
参数名 | 类型 | 长度 | 可空 | 说明 |
Order_no | string | 50 | Not null | 订单号 |
money | double | 16 | Not null | 金额 |
Order_date | string | 14 | Not null | 订单日期 |
Bank_no | string | 50 | Not null | 银行流水号 |
Bank_date | string | 14 | Not null | 银行处理日期 |
Validate_Key | string | 100 | Not null | 加密后的字符串 |
双方参数约定好后,那么我们就看系统具体的实施:
1. 首先是bank约定的加密方法(C#实现)
/// <summary> /// Encrypt the params will be sent to bank /// </summary> /// <param name="input"></param> /// <returns></returns> private string EncryptParams(string input) { MD5 md5 = MD5.Create(); byte[] bitChar = md5.ComputeHash(Encoding.Default.GetBytes(input)); StringBuilder sb = new StringBuilder(); foreach (byte b in bitChar) { sb.Append(b.ToString("x2")); } return sb.ToString(); } /// <summary> /// Sort the params to send|receive between shop and bank /// </summary> /// <param name="orderNo">shop order no</param> /// <param name="money">shop money</param> /// <param name="orderDate">shop date</param> /// <param name="bankNo">bank no</param> /// <param name="bankDate">bank date</param> /// <param name="encryptType">0:Send| 1:Receive</param> /// <returns></returns> public string ParamsHandle( string orderNo, string money, string orderDate, string bankNo, string bankDate, int encryptType) { string orderNoEx = "order_no=" + orderNo; string moneyEx = "money=" + money; string orderDateEx = "order_date=" + orderDate; string bankNoEx = "bank_no=" + bankNo; string bankDateEx = "bank_date=" + bankDate; string[] paramArr; if (0 == encryptType) //Send { paramArr = new string[] { orderNoEx, moneyEx, orderDateEx }; } else if (1 == encryptType) //Receive { paramArr = new string[] { orderNoEx, moneyEx, orderDateEx, bankNoEx, bankDateEx }; } else { return ""; } //BubbleSort for (int i = 0; i < paramArr.Length - 1; i++) { if (string.CompareOrdinal(paramArr[i], paramArr[i + 1]) >= 0) { string temp = paramArr[i]; paramArr[i] = paramArr[i + 1]; paramArr[i + 1] = temp; } } //Join StringBuilder sb = new StringBuilder(); for (int i = 0; i < paramArr.Length; i++) { sb.Append(paramArr[i] + "&"); } string secretKey = System.Configuration.ConfigurationManager.AppSettings["key"]; sb.Insert(0, String.Format("{0}&", secretKey)); string tempEncrypt = EncryptParams(sb.ToString().Substring(0, sb.Length - 1)); sb.Append("validate_key=" + tempEncrypt); return sb.ToString(); }
2. 然后再看shop提交参数到银行的实现:(C#,asp.net)
private void Send(string orderNo, string money, string orderDate) { string finalParms = ParamsHandle(orderNo, money, orderNo, "", "", 0); Response.Redirect("Bank.do?" + finalParms); }
3. 最后是bank支付成功后,跳转到shop,shop的接收页的代码(C#,asp.net)
protected void Page_Load(object sender, EventArgs e) { string orderNo = SafeRequest(Request["order_no"]); string money = SafeRequest(Request["money"]); string orderDate = SafeRequest(Request["order_date"]); string bankNo = SafeRequest(Request["bank_no"]); string bankDate = SafeRequest(Request["bank_date"]); string validateKey = SafeRequest(Request["validate_key"]); DealPayed(orderNo, money, orderDate, bankNo, bankDate, validateKey); } private void DealPayed(string orderNo, string money, string orderDate, string bankNo, string bankDate, string validateKey) { string validateStr = ParamsHandle(orderNo, money, orderDate, bankNo, bankDate, 1); if (String.Compare(validateKey, validateStr, false) == 0) { //再处理,发货等等 } else { //参数被篡改,报错 } } private string SafeRequest(object obj) { string result = String.Empty; try { result = Convert.ToString(obj); return result; } catch { return String.Empty; } }
4.
5.
6.