繁体   English   中英

有没有更简单的方法来计算此MD5哈希?

[英]Is there a simpler way to calculate this MD5 hash?

我正在实施托管的结帐,托管的结帐应将用户重定向到我的网站,以便我可以显示自定义收据页面。

这是我返回的示例查询字符串:

trnApproved = 0&trnId =千万&MESSAGEID = 71&的MessageText =拒绝&AUTHCODE = 000000&的responseType = T&trnAmount = 20.00&trnDate = 9%2f23%2f2011 + 9%3a30%3a56 + AM&trnOrderNumber = 1000000&trnLanguage =主机&trnCustomerName =姓+名字&trnEmailAddress = something_something%40gmail.com&trnPhoneNumber = 1235550123&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应用程序中的人,所以我认为简单的验证不应该如此复杂。

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

这是使用查询字符串的一种更好的方法:

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吗? 您可以这样做,然后附加到查询字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM