2011-09-23 81 views
2

我正在实施托管结帐,托管结帐应该将用户重定向回我的网站,以便我可以显示自定义收据页面。有没有更简单的方法来计算这个MD5哈希?

这是一个示例查询字符串,我会回来:

trnApproved = 0 & trnId =千万& MESSAGEID = 71 & =的MessageText被拒& AUTHCODE = 000000 &的responseType = T & trnAmount = 20.00 & trnDate = 9%2f23%2f2011 + 9%3a30%3a56 + AM & trnOrderNumber = 1000000 & trnLanguage = eng & trnCustomerName =名字+姓氏& trnEmailAddress = something_something%40gmail.com & trnPhoneNumber = 123555 avsProcessed = 0 & avsId = 0 & avsResult = 0 & avsAddrMatch = 0 & avsPostalMatch = 0 & avsMessage =地址+验证+ +不进行对于+ + +这个交易。 & cvdId = 3 & cardType = VI & trnType = P & PAYMENTMETHOD = CC & REF1 = 9dae6af7-7c22-4697-B23A-413d8a129a75 & REF2 = & REF3 = & REF4 = & REF5 = &散列值= 33dacf84682470f267b2cc6d528b1594

为了验证请求,我应该从查询字符串的末尾删除&hashValue=f3cf58ef0fd363e0c2241938b04f1068,然后附加一个键。然后我执行整个字符串的MD5哈希,结果应该是33dacf84682470f267b2cc6d528b1594,与原始相同。

这很容易,除了一些领域对我造成问题。这是我使用的代码(从虚拟应用程序中获得,因此可以忽略一些不好的编码):

// Split up the query string parameters 
string[] parameters = GetQueryString().Split(new[] { "&" }, StringSplitOptions.None); 
var querySet = new List<string>(); 

// Rebuild the query string, encoding the values. 
foreach (string s in parameters) 
{ 
    // Every field that contains a "." will need to be encoded except for trnAmount 
    querySet.Add(param.Contains("trnAmount") ? param : UrlEncodeToUpper(param)); 
} 

// Create the querystring without the hashValue, we need to calculate our hash without it. 
string qs = string.Join("&", querySet.ToArray()); 
qs = qs.Substring(0, qs.IndexOf("&hashValue")); 
qs = qs + "fb76124fea73488fa11995dfa4cbe89b"; 

var encoding = new UTF8Encoding(); 
var md5 = new MD5CryptoServiceProvider(); 
var hash = md5.ComputeHash(encoding.GetBytes(qs)); 

var calculatedHash = BitConverter.ToString(hash).Replace("-", String.Empty).ToLower(); 

这就是以UrlEncode方法我用。

private static string UrlEncodeToUpper(string value) 
{ 
    // Convert their encoding into uppercase so we can do our hash 
    value = Regex.Replace(value, "(%[0-9af][0-9a-f])", c => c.Value.ToUpper()); 
    // Encode the characters that they missed 
    value = value.Replace("-", "%2D").Replace(".", "%2E").Replace("_", "%5F"); 
    return value; 
} 

这一切工作(直到有人进入角色,我还没有计入),除了这似乎更复杂比它应该是。我知道我不是唯一必须将这个HCO实现到ASP.NET应用程序中的人,所以我不认为简单的验证应该如此复杂。

我错过了一个更简单的方法来做到这一点?必须遍历字段,编码其中的一些而跳过其他字符,将其编码转换为大写字母,然后有选择地替换字符似乎有点奇怪。

+1

Yay GET请求改变状态......更好的希望谷歌有足够的钱来支付它将要从你的网站上购买的所有东西! – Blindy

+2

@Bindind,改变状态?此请求没有任何变化。我们只向将要进行身份验证的用户显示收据。 – Brandon

+0

你可以做一个帖子,而不是使用查询字符串吗? –

回答

1

这里有一个更好的方式与查询字符串的工作:

var queryString = "trnApproved=0&trnId=10000000&messageId=71&messageText=Declined&authCode=000000&responseType=T&trnAmount=20.00&trnDate=9%2f23%2f2011+9%3a30%3a56+AM&trnOrderNumber=1000000&trnLanguage=eng&trnCustomerName=FirstName+LastName&trnEmailAddress=something_something%40gmail.com&trnPhoneNumber=1235550123&avsProcessed=0&avsId=0&avsResult=0&avsAddrMatch=0&avsPostalMatch=0&avsMessage=Address+Verification+not+performed+for+this+transaction.&cvdId=3&cardType=VI&trnType=P&paymentMethod=CC&ref1=9dae6af7-7c22-4697-b23a-413d8a129a75&ref2=&ref3=&ref4=&ref5=&hashValue=33dacf84682470f267b2cc6d528b1594"; 
var values = HttpUtility.ParseQueryString(queryString); 
// remove the hashValue parameter 
values.Remove("hashValue"); 
var result = values.ToString(); 
// At this stage result = trnApproved=0&trnId=10000000&messageId=71&messageText=Declined&authCode=000000&responseType=T&trnAmount=20.00&trnDate=9%2f23%2f2011+9%3a30%3a56+AM&trnOrderNumber=1000000&trnLanguage=eng&trnCustomerName=FirstName+LastName&trnEmailAddress=something_something%40gmail.com&trnPhoneNumber=1235550123&avsProcessed=0&avsId=0&avsResult=0&avsAddrMatch=0&avsPostalMatch=0&avsMessage=Address+Verification+not+performed+for+this+transaction.&cvdId=3&cardType=VI&trnType=P&paymentMethod=CC&ref1=9dae6af7-7c22-4697-b23a-413d8a129a75&ref2=&ref3=&ref4=&ref5= 

// now add some other query string value 
values["foo"] = "bar"; // you can stuff whatever you want it will be properly url encoded 

然后,我不太明白你想要做什么。你想计算一个MD5的结果?你可以做到这一点,然后追加到查询字符串。

+0

问题是,我不能只是删除hash值并执行散列,因为在做散列之前,我需要通过字段并“修复”他们发送的响应中某些字符的编码我。 – Brandon

+1

@Brandon,你是什么意思*修正一些字符的编码*?你没有一个真正的查询字符串? –

+0

是的。当我调用HttpContext.Current.QueryString时,我得到了我在我的问题中发布的结果。我无法对该查询字符串执行MD5散列,因为它提供了不正确的结果。为了获得正确的结果,我需要执行我在问题中提到的修改。基本上,我不能像原样使用查询字符串,因为它不是HCO提供程序用来计算哈希值的字符串。 – Brandon