HMAC验证失败,代码为403

时间:2015-08-07 05:07:15

标签: c# hmac

过去三天我一直在探索payeezy api。我只是从C#应用程序发出一个简单的http Web请求。我已经按照所有步骤提及并正确验证了所有步骤。以下是每件商品的详细信息。

  1. API密钥: - 我已验证我的api密钥正确无误。
  2. API秘密: - 这也是正确的。
  3. 商家代币: - 也经过验证。
  4. Nonce: - 我创建了加密强随机数,如下所示。

    RandomNumberGenerator rng = new RNGCryptoServiceProvider();
    byte[] nonceData = new byte[18];
    rng.GetBytes(nonceData);
    string nonce = BitConverter.ToUInt64(nonceData,0).ToString();  
    
  5. 时间戳: -

    string timestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
    
  6. 有效负载: -

    {"merchant_ref":"Astonishing-Sale","transaction_type":"authorize","method":"credit_card","amount":"1299","currency_code":"USD","credit_card":{"type":"visa","cardholder_name":"John Smith","card_number":"4788250000028291","exp_date":"1020","cvv":"123"}}
    
  7. 然后我创建了HMAC如下。

    private string CreateAuthorization(string data, string secret)
    {
        // data is in following format.
        //  data = apiKey + nonce + timestamp + token + payload;
        secret = secret ?? "";
        using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
        {
            byte[] hashdata = hmacsha256.ComputeHash(Encoding.UTF32.GetBytes(data));
            return Convert.ToBase64String(hashdata);
        }
    }
    
  8. 现在我得到了hmac验证错误。我生成的hmac字符串是64位,而在你的网站上是docs,sandbox是86位。
  9. 请你帮我解决这个问题,因为我在过去三天里遇到了这个问题。 感谢

2 个答案:

答案 0 :(得分:1)

这些是“HMAC验证失败”的常见原因:

  1. API密钥和/或API密码不正确。
  2. API密钥中的前导或尾随空格,API密钥,商家令牌。
  3. HTTP标头中的时间戳不是以毫秒为单位。
  4. HTTP标头中的时间戳不代表EPOCH时间。
  5. HTTP标头中的时间戳不在我们服务器时间的5分钟内。
  6. 系统时间不准确。
  7. 以下是生成HMAC的示例c#代码:

    public byte[] CalculateHMAC(string data, string secret)
        {
            HMAC hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            byte[] hmac2Hex = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(data));
    
            string hex = BitConverter.ToString(hmac2Hex);
            hex = hex.Replace("-","").ToLower();
            byte[] hexArray = Encoding.UTF8.GetBytes(hex);
            return hexArray;
        }
    
    protected void Button1_Click(object sender, EventArgs e)
    {                     
        string jsonString = "{ \"merchant_ref\": \"MVC Test\", \"transaction_type\": \"authorize\", \"method\": \"credit_card\", \"amount\": \"1299\", \"currency_code\": \"USD\", \"credit_card\": { \"type\": \"visa\", \"cardholder_name\": \"Test Name\", \"card_number\": \"4005519200000004\", \"exp_date\": \"1020\", \"cvv\": \"123\" } }";
    
        Random random = new Random();
        string nonce = (random.Next(0, 1000000)).ToString();
    
        DateTime date = DateTime.UtcNow;
        DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        TimeSpan span = (date - epoch);
        string time = span.TotalSeconds.ToString();
    
        string token = Request.Form["token"];//Merchant token
        string apiKey = Request.Form["apikey"];//apikey
        string apiSecret = Request.Form["apisecret"];//API secret
        string hashData = apiKey+nonce+time+token+jsonString;
    
        string base64Hash = Convert.ToBase64String(CalculateHMAC(hashData, apiSecret));
    
        string url = "https://api-cert.payeezy.com/v1/transactions";
    
        //begin HttpWebRequest
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
    
        webRequest.Method = "POST";
        webRequest.Accept = "*/*";
        webRequest.Headers.Add("timestamp", time);
        webRequest.Headers.Add("nonce", nonce);
        webRequest.Headers.Add("token", token);
        webRequest.Headers.Add("apikey", apiKey);
        webRequest.Headers.Add("Authorization", base64Hash );
        webRequest.ContentLength = jsonString.Length;
        webRequest.ContentType = "application/json";
    
        StreamWriter writer = null;
        writer = new StreamWriter(webRequest.GetRequestStream());
        writer.Write(jsonString);
        writer.Close();
    
        string responseString;
        try
            {
                using(HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader responseStream = new StreamReader(webResponse.GetResponseStream()))
                    {
                        responseString = responseStream.ReadToEnd();
                        request_label.Text = "<h3>Request</h3><br />" + webRequest.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(jsonString);
                        response_label.Text = "<h3>Response</h3><br />" + webResponse.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(responseString);
                    }
                }
            }
        catch (WebException ex)
        {
            if (ex.Response != null) 
            {
                using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response) 
                {
                    using (StreamReader reader = new StreamReader(errorResponse.GetResponseStream())) 
                    {
                        string remoteEx = reader.ReadToEnd();
                        error.Text = remoteEx;
                    }
                }
            }           
        }
    }
    

答案 1 :(得分:1)

我一直致力于整合,而且工作得很好;也许你可以偷看 https://github.com/clifton-io/Clifton.Payment

具体来说,你想看看这里: https://github.com/clifton-io/Clifton.Payment/blob/cc4053b0bfe05f2453dc508e96a649fc138b973c/Clifton.Payment/Gateway/Payeezy/PayeezyGateway.cs#L66

祝你好运:)