代码改变世界

在线支付平台(大多数)采用的加密方法之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支付成功后,跳转到shopshop的接收页的代码(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.