Есть ли более простой способ вычислить этот хэш MD5? - PullRequest
2 голосов
/ 23 сентября 2011

Я работаю над реализацией размещенной проверки, и предполагается, что размещенная проверка перенаправляет пользователя обратно на мой веб-сайт, чтобы я мог показать пользовательскую страницу квитанции.

Это образец строки запроса, которую я получу обратно:

trnApproved = 0 & trnId = 10000000 & MessageId = 71 & MessageText = Отклонено & AuthCode = 000000 & responseType = Т & trnAmount = 20,00 & trnDate = 9% 2f23% 2f2011 + 9% 3A30% 3a56 + AM & trnOrderNumber = 1000000 & trnLanguage = анг & trnCustomerName = FirstName + LastName & trnEmailAddress = something_something% 40gmail.com & trnPhoneNumber = 1235550123 & avsProcessed = 0 & avsId = 0 & avsResult = 0 & avsAddrMatch = 0 & avsPostalMatch = 0 & avsMessage = Адрес + Проверочный + не + выполняется + для + это + транзакции. & cvdId = 3 & cardType = VI & trnType = Р & 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 Ответ

1 голос
/ 23 сентября 2011

Вот лучший способ работы со строками запроса:

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 на результат? Вы можете сделать это, а затем добавить к строке запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...