简体   繁体   English

错误: - {“code”:“403”,“message”:“HMAC验证失败”}

[英]error :- {“code”:“403”, “message”:“HMAC validation Failure”}

Here i am attaching code and a link consist of full code , have a look on it:- My authorization header seams to be coming of same length as mentioned in official site of payeezy.I have also make my hmacString of same order as mentioned in this link ( https://developer.payeezy.com/content/hmac-validation-failure ) . 在这里我附加代码和链接由完整代码组成,看看它: - 我的授权标题接缝与payeezy官方网站中提到的相同长度。我也使我的hmacString与上面提到的相同的顺序此链接( https://developer.payeezy.com/content/hmac-validation-failure )。 After doing all this i am still getting this same issue 完成所有这些后,我仍然遇到同样的问题

public static String excutePost(String urlParameters) throws IOException {
        URL url = new URL("https://api-cert.payeezy.com/v1/transactions");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        try {
            // Create connection
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", headerContentType);
            connection.setRequestProperty("apikey ", apikey);
            connection.setRequestProperty("token", MerchantToken);
            connection
                    .setRequestProperty("Authorization", authorizationHeader);
            connection.setRequestProperty("timestamp", ""+epoch);
            connection.setRequestProperty("nonce", ""+nonce);
            connection.setDoOutput(true);
            connection.setReadTimeout(30000);

            // Send request
            DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();

            // Get Response
            InputStream is = connection.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer();
            while ((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            return response.toString();

        } catch (Exception e) {

            e.printStackTrace();
            return null;

        } finally {

            if (connection != null) {
                connection.disconnect();
            }
        }
    }

Here is full java class code :- http://piratepad.net/ep/pad/view/ro.WwZ9v6FX1a6/latest 这是完整的java类代码: - http://piratepad.net/ep/pad/view/ro.WwZ9v6FX1a6/latest

I finally solve this error by sending direct String as parameter in api url hit.Here i am posting some of my code which solve my error :- 我终于通过在api url hit中发送直接String作为参数来解决这个错误。我发布了一些解决我错误的代码: -

 String str = "{\\"amount\\":\\"1299\\",\\"merchant_ref\\":\\"Astonishing-Sale\\",\\"transaction_type\\":\\"authorize\\",\\"credit_card\\":{\\"card_number\\":\\"4788250000028291\\",\\"cvv\\":\\"123\\",\\"exp_date\\": \\"1020\\",\\"cardholder_name\\": \\"John Smith\\",\\"type\\": \\"visa\\"},\\"method\\": \\"credit_card\\",\\"currency_code\\": \\"USD\\"}"; 

now this String will be used in generating my authorisation key. 现在,此String将用于生成我的授权密钥。 the whole process is defined below :- 整个过程定义如下 : -

 getSecurityKeys(apikey, pzsecret,str); private static Map<String, String> getSecurityKeys(String appId, String secureId, String payLoad) throws Exception { Map<String, String> returnMap = new HashMap<String, String>(); try { returnMap.put(NONCE, Long.toString(nonce)); returnMap.put(APIKEY, appId); returnMap.put(TIMESTAMP, Long.toString(System.currentTimeMillis())); returnMap.put(TOKEN, MerchantToken); returnMap.put(APISECRET, pzsecret); returnMap.put(PAYLOAD, payLoad); returnMap.put(AUTHORIZE, getMacValue(returnMap)); authorizationHeader = returnMap.get(AUTHORIZE); return returnMap; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.getMessage(), e); } } public static String getMacValue(Map<String, String> data) throws Exception { Mac mac = Mac.getInstance("HmacSHA256"); String apiSecret = data.get(APISECRET); SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"); mac.init(secret_key); StringBuilder buff = new StringBuilder(); buff.append(data.get(APIKEY)).append(data.get(NONCE)) .append(data.get(TIMESTAMP)); if (data.get(TOKEN) != null) buff.append(data.get(TOKEN)); if (data.get(PAYLOAD) != null) buff.append(data.get(PAYLOAD)); byte[] macHash = mac.doFinal(buff.toString().getBytes("UTF-8")); String authorizeString = Base64.encodeBase64String(toHex(macHash)); return authorizeString; } 
Now finally you can pass direct String(ie str) as parameter in hitting post api in java. 现在最后你可以在java中命中post api时传递直接String(即str)作为参数。

hope it helps other to integrate payeezy payment gateway without using any dependencies. 希望它可以帮助其他人集成payeezy支付网关而不使用任何依赖。 Happy Codeing!!! 快乐编码!!!

You must generate a new timestamp and nonce for every request, ie, every new request must have its unique timestamp and nonce . 您必须为每个请求生成新的timestampnonce ,即每个新请求必须具有其唯一的timestampnonce

In java, timestamp can be set as System.currentTimeMillis() and nonce can be set using UUID ( UUID.randomUUID().toString() ). 在java中, timestamp可以设置为System.currentTimeMillis()并且可以使用UUIDUUID.randomUUID().toString() )设置nonce

Finally, make sure that your Authorization is correctly computed (I see they use HMAC-SHA1 using API secret key). 最后,确保正确计算了Authorization (我看到他们使用API​​密钥使用HMAC-SHA1 )。

I hope this helps. 我希望这有帮助。


Edit : As suspected, it's your HMAC-SHA1 Authorization value that is incorrect. 编辑 :怀疑,这是您的HMAC-SHA1授权值不正确。 I get the following response when running your code (after few coding of my own). 运行代码时我得到以下响应(经过我自己的编码)。

Connection = keep-alive
Content-Length = 51
Content-Type = application/json
{"code":"403", "message":"HMAC validation Failure"}

Make sure that you compute your HMAC-SHA1 value correctly (as I said above). 确保正确计算HMAC-SHA1值(如上所述)。

See the below (updated) code that you can compile and run for yourself. 请参阅下面(更新的)您可以自行编译和运行的代码。 You will need Java 8 as it comes with Base 64 encoder/decoder now. 现在,您将需要Java 8,因为它带有Base 64编码器/解码器。

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.net.URI;
import java.net.URL;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.TimeZone;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

//import org.apache.commons.codec.binary.Base64;

public class MainJava {
    private static final String    myEncoding            = "UTF-8";
    private static final String    myMessageDigest        = "SHA-1";
    private static final String    myKeySpec            = "HmacSHA1";
    private static String        NEWLINE                = "\n";
    private static String        authorizationHeader;
    private static String        contentSha1;
    // private static String keyId = "230297";
    // private static String hmacKey = "tcwR9r1OR85V9bcV5tc7a9d1XkWigjqY";
    private static String        ApiSecretkey        = "0779eb593286b278aaf8cfcf83c8e33bc757d53a8a642b53d24d63bda844da5b";
    private static String        MerchantToken        = "fdoa-a480ce8951daa73262734cf102641994c1e55e7cdf4c02b6";
    private static String        reportingToken        = "e56a0223d0415067";
    private static String        apikey                = "XSjbv8PLDINJ28qXLEYAhcrz8rxKXQ4Y";
    private static long            nonce;
    public static String        headerContentType    = "application/json";
    private static long            epoch;

    public static void main(String[] args) throws Exception {
        String json_string_dataTwo = "{\"type\":\"visa\",\"cardholder_name\":\"John Smith\",\"card_number\":\"4788250000028291\",\"exp_date\":1020,\"cvv\":\"123\"}";
        // String json_string =
        // "{\"gateway_id\":\"AI2010-01\",\"password\":\"w226638qtot48xu503zumwt2iy46g26q\",\"transaction_type\":\"00\",\"amount\":10,\"cardholder_name\":\"test\",\"cc_number\":\"4111111111111111\",\"cc_expiry\":\"1219\"}";
        String json_string_data = "{\"merchant_ref\":\"Astonishing-Sale\",\"transaction_type\":\"authorize\",\"method\":\"credit_card\",\"amount\":1299,\"currency_code\":\"USD\",\"credit_card\":"
                + json_string_dataTwo + "}";
        // "{\r\n  \"merchant_ref\": \"Astonishing-Sale\",\r\n  \"transaction_type\": \"authorize\",\r\n  \"method\": \"credit_card\",\r\n  \"amount\": \"1299\",\r\n  \"currency_code\": \"USD\",\r\n  \"credit_card\": {\r\n    \"type\": \"visa\",\r\n    \"cardholder_name\": \"John Smith\",\r\n    \"card_number\": \"4788250000028291\",\r\n    \"exp_date\": \"1020\",\r\n    \"cvv\": \"123\"\r\n  }\r\n}";

        epoch = System.currentTimeMillis();// / 1000;
        // nonce = UUID.randomUUID().toString();
        nonce = Math.abs(SecureRandom.getInstance("SHA1PRNG").nextLong());
        contentSha1 = contentSha1(json_string_data);
        authorizationHeader = authHeader(epoch, contentSha1);
        System.out.println(excutePost(json_string_data));
    }

    private static String authHeader(long hashTime, String contentSha1) {
        String authorizationHeader = null;
        try {
            String hmacString = "POST" + NEWLINE + "application/json" + NEWLINE + contentSha1 + NEWLINE + hashTime + NEWLINE + apikey + NEWLINE
                    + new URI("https://api-cert.payeezy.com/v1/transactions");

            return sha1(hmacString, ApiSecretkey);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String contentSha1(String content) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] sha1hash = new byte[40];
        md.update(content.getBytes("UTF-8"), 0, content.length());
        sha1hash = md.digest();
        return convertToHex(sha1hash);
    }

    private static String convertToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            int halfbyte = data[i] >>> 4 & 0xF;
            int two_halfs = 0;
            do {
                if ((0 <= halfbyte) && (halfbyte <= 9))
                    buf.append((char) (48 + halfbyte));
                else
                    buf.append((char) (97 + (halfbyte - 10)));
                halfbyte = data[i] & 0xF;
            } while (two_halfs++ < 1);
        }
        return buf.toString();
    }

//     private static String sha1(String s, String keyString) {
//     Base64 base64 = new Base64();
//     try {
//     SecretKeySpec key = new SecretKeySpec(keyString.getBytes("UTF-8"),
//     "HmacSHA1");
//     Mac mac = Mac.getInstance("HmacSHA1");
//     mac.init(key);
//     byte[] bytes = mac.doFinal(s.getBytes("UTF-8"));
//    
//     return new String(base64.encode(bytes));
//     } catch (Exception e) {
//     throw new RuntimeException(e);
//     }
//     }
    private static String sha1(String s, String keyString) {
        byte[] bytes = null;
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(keyString.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            bytes = sha256_HMAC.doFinal(s.getBytes("UTF-8"));
            //return new String(Base64.encodeBase64String(bytes));
        } catch (Exception e) {
            System.out.println("Error");
        }
        return  Base64.getEncoder().encodeToString(bytes);
    }

    private static String hashTime() {
        String time = getUTCFormattedDate("yyyy-MM-dd'T'HH:mm:ss'Z'");

        return time;
    }

    private static String getUTCFormattedDate(String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        return dateFormat.format(new Date());
    }

    public static String excutePost(String urlParameters) throws IOException {
    System.out.println(urlParameters);
    System.out.println(headerContentType);
    System.out.println(MerchantToken);
    System.out.println(authorizationHeader);
    System.out.println(epoch);
    System.out.println(nonce);
        URL url = new URL("https://api-cert.payeezy.com/v1/transactions");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        try {
            // Create connection
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", headerContentType);
            connection.setRequestProperty("apikey ", apikey);
            connection.setRequestProperty("token", MerchantToken);
            connection.setRequestProperty("Authorization", authorizationHeader);
            connection.setRequestProperty("timestamp", "" + epoch);
            connection.setRequestProperty("nonce", "" + nonce);
            connection.setDoOutput(true);
            connection.setReadTimeout(30000);

            // Send request
            DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();

            // Get Response
            InputStream is = null;
            int statusCode = connection.getResponseCode();

        try {
            is = connection.getInputStream();
        } catch (IOException e) {
            if (statusCode >= 400) {
                is = connection.getErrorStream();
            }
        }
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer();
            while ((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            return response.toString();

        } catch (Exception e) {

            e.printStackTrace();
            return null;

        } finally {

            if (connection != null) {
                connection.disconnect();
            }
        }
    }

}

My only issue is with the character encoding, where I assume UTF-8. 我唯一的问题是字符编码,我假设UTF-8。 I suspect that the error lies elsewhere. 我怀疑错误在于其他地方。

        // Send request
        byte[] data = urlParameters.getBytes(StandardCharsets.UTF_8);
        BufferedOutputStream wr = new BufferedOutputStream(connection.getOutputStream());
        wr.writeBytes(data);
        wr.close();

        // Get Response
        InputStream is = connection.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is,
                StandardCharsets.UTF_8));

And \\r , CR, does not serve as line separator (apart from old MacOS). 并且\\r ,CR,不作为行分隔符(除了旧的MacOS)。

           response.append("\r\n"); // Or '\n'

暂无
暂无

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

相关问题 AngularJS显示403 HTTP错误代码的自定义错误消息/页面 - AngularJS show custom error message / page for 403 http error code Spring 验证 @AssertTrue 自定义错误代码/消息 - Spring validation @AssertTrue custom error code/message Spring:如何解决验证错误 - &gt;错误代码 - &gt;错误消息 - Spring: How to resolve a validation error -> error code -> error message 向 SQS 发布消息时出错:AmazonSQS; 状态码:403; 错误代码:RequestThrottled - Getting error while publishing message to SQS: AmazonSQS; Status Code: 403; Error Code: RequestThrottled 什么是 keyed-HMAC(哈希消息验证码) - what is keyed-HMAC (Hash Message Authentication Code) Springboot 中的授权失败返回带有 403 状态消息的空体 - Authorization failure in Springboot returns empty body with 403 status message 错误原因:java.io.IOException:{“错误”:{“代码”:403,“消息”:“权限被拒绝。无法执行此操作”}} - error Caused by: java.io.IOException: { "error": { "code": 403, "message": "Permission denied. Could not perform this operation" }} 需要帮助修改代码以进行输入验证和错误消息 - Need help modifying code for input validation and error message 无法使用AWS SES API发送电子邮件。 错误消息,状态码:403 - Emails could not be sent using AWS SES APIs. Error message with Status Code: 403 “状态”:403,“错误”:“禁止”“消息”:邮递员弹簧启动代码中的“访问被拒绝” - "status": 403, "error": "Forbidden" "message": "Access Denied" in postman spring boot code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM