微信並無給ASP.net用戶提供一個很好的實例,只好苦心研究,通過一個下午的努力和N次測試,終於知道如何解密和驗籤notify的數據了,如下是我實現的代碼,好東西需分享給各位朋友:(如下的商戶編號我已經修改過,因此沒有返回true,請根據本身的實際數據測試)git
using System;算法
using System.Collections.Generic;微信
using System.Linq;測試
using System.Web;ui
using System.Drawing;編碼
using System.Drawing.Imaging;加密
using System.IO;spa
using System.Drawing.Drawing2D;.net
using Ganxike.Bll;對象
using Ganxike.Entity;
using System.Text;
using System.Security.Cryptography;
namespace Ganxike.Front
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//bank_billno:201407013021057579
//bank_type:2011 //付款銀行代號
//discount:0 //折扣價格(若是有)
//fee_type:1 //幣種
//input_charset:GBK //編碼字符
//notify_id:cEBCIhJpi4A6JrwjzYjarrY4-y04msE2T7Ixq0U19wcntbPlOXrtshGlKcEhGsN-uC78fnIcPi6mIFpl2UfDxW3R1yPv7yRQ //通知ID
//out_trade_no:2033179023 //商戶訂單號
//partner:1218656301 //商戶號
//product_fee:1 //物品費用(分)
//sign:24897219B33E59DC7FA49FEC3CE0D1C3 //簽名
//sign_type:MD5 //簽名方式
//time_end:20140701145333 //支付完成時間
//total_fee:1 //總金額(分)
//trade_mode:1 //交易模式(1即時到賬)
//trade_state:0 //交易狀態(0成功)
//transaction_id:1218656301201407013164175338 //訂單號
//transport_fee:0 //物流費用
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("bank_billno", "201407013021057579");
parameters.Add("bank_type", "2011");
parameters.Add("discount", "0");
parameters.Add("fee_type", "1");
parameters.Add("input_charset", "GBK");
parameters.Add("notify_id", "cEBCIhJpi4A6JrwjzYjarrY4-y04msE2T7Ixq0U19wcntbPlOXrtshGlKcEhGsN-uC78fnIcPi6mIFpl2UfDxW3R1yPv7yRQ");
parameters.Add("out_trade_no", "2033179023");
parameters.Add("partner", "1218656301");
parameters.Add("product_fee", "1");
parameters.Add("sign_type", "MD5");
parameters.Add("time_end", "20140701145333");
parameters.Add("total_fee", "1");
parameters.Add("trade_mode", "1");
parameters.Add("trade_state", "0");
parameters.Add("transaction_id", "1218656301201407013164175338");
parameters.Add("transport_fee", "0");
//將全部參數按Key字母排序
string content = GetSignContent(parameters);
Response.Write(VerifySignature(content, "24897219BABCDC7FA49DECE0D1C3", "20a01775b1234714920a47a6321cb292"));
}
/// <summary>
/// 驗證簽名
/// </summary>
/// <param name="content">排序後的全部參數(不包括sign參數)</param>
/// <param name="sign">合做商傳過來的sign簽名(對參數加密後的MD5)</param>
/// <param name="ourKey">咱們用於簽名的密鑰(用於解密的一串字符)</param>
/// <returns></returns>
public static bool VerifySignature(String content, String sign, String ourKey)
{
string signResult = WXPayMD5(content + "&key=" + ourKey).ToUpper();
return (sign == signResult);
}
/// <summary>
/// MD5加密
/// </summary>
/// <param name="s">需加密的字符</param>
/// <returns></returns>
public static String WXPayMD5(String s)
{
char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F' };
try
{
byte[] btInput = System.Text.Encoding.Default.GetBytes(s);
// 得到MD5摘要算法的 MessageDigest 對象
MD5 mdInst = System.Security.Cryptography.MD5.Create();
// 使用指定的字節更新摘要
mdInst.ComputeHash(btInput);
// 得到密文
byte[] md = mdInst.Hash;
// 把密文轉換成十六進制的字符串形式
int j = md.Length;
char[] str = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++)
{
byte byte0 = md[i];
str[k++] = hexDigits[(int)(((byte)byte0) >> 4) & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new string(str);
}
catch (Exception e)
{
Console.Error.WriteLine(e.StackTrace);
return null;
}
}
/// <summary>
/// 將字典全部值按Key字母順序合併成字符串
/// </summary>
/// <param name="parameters">字典類</param>
/// <returns>字符串</returns>
public static string GetSignContent(IDictionary<string, string> parameters)
{
// 第一步:把字典按Key的字母順序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
// 第二步:把全部參數名和參數值串在一塊兒
StringBuilder query = new StringBuilder("");
while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
{
query.Append(key).Append("=").Append(value).Append("&");
}
}
string content = query.ToString().Substring(0, query.Length - 1);
return content;
}
}
}