{"__v":0,"_id":"575676128749830e00681e8f","category":{"version":"575676128749830e00681e82","project":"55a4d5531a5f991700a9409e","_id":"575676128749830e00681e86","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-09-23T14:31:03.400Z","from_sync":false,"order":1,"slug":"authorization","title":"Authorization"},"parentDoc":null,"project":"55a4d5531a5f991700a9409e","user":"560266564f15002100ee444b","version":{"__v":2,"_id":"575676128749830e00681e82","project":"55a4d5531a5f991700a9409e","createdAt":"2016-06-07T07:21:54.005Z","releaseDate":"2016-06-07T07:21:54.005Z","categories":["575676128749830e00681e83","575676128749830e00681e84","575676128749830e00681e85","575676128749830e00681e86","575676128749830e00681e87","575676128749830e00681e88","575676128749830e00681e89","575676128749830e00681e8a","575676128749830e00681e8b","580c5ff36c35230f003d3b49"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.0.0","version":"2.0"},"updates":["5630b2da242cda1900198ac8"],"next":{"pages":[],"description":""},"createdAt":"2015-09-23T14:54:49.865Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"The message signature should be sent in the Authorization header as parameter. The following section describes the needed parameters as well as the steps needed in order to create the signature. Each step is exemplified with code samples. \n[block:parameters]\n{\n \"data\": {\n \"0-0\": \"store key\",\n \"0-1\": \"The key used to identify the specific shop. This key is available in the Retailer portal.\",\n \"1-0\": \"timestamp\",\n \"1-1\": \"The time when the message was created.\\n\\n***Important**: Please note that the provided value should be the current Unix timestamp*\\n\\n***Warning**: Messages older than 15 minutes will be rejected in order to prevent replay attacks.*\",\n \"2-0\": \"nonce\",\n \"2-1\": \"The nonce (used once) is a unique and random string that is meant to uniquely identify each request.\",\n \"3-1\": \"Represents the http request method.\\n***Important**: The http request method should be sent in uppercase.\",\n \"3-0\": \"method\",\n \"4-0\": \"url\",\n \"4-1\": \"The URL to the resource including query strings to lower case.\",\n \"5-0\": \"content\",\n \"5-1\": \"Represents the body of the request. We assume that the message body will be in JSON format.\\n\\n***Important**: The JSON body must be JavaScript encoded!\",\n \"6-0\": \"shared secret\",\n \"6-1\": \"Base64 encoded HMACSHA256 key. \\n***Important**: PHP 5.4 added support for enc_type parameter\"\n },\n \"cols\": 2,\n \"rows\": 7\n}\n[/block]\n## Generate Signature\n1. UTF-8 Encode the content and compute the MD5 digest. Convert the MD5 digest to base 64 string. In case the content is empty(for example in case of a get) the result of this step should be an empty string. \n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"var digestBase64 = String.Empty;\\nif (String.IsNullOrWhiteSpace(contentAsJson))\\n{\\n var content = Encoding.UTF8.GetBytes(contentAsJson);\\n byte[] requestContentHash = MD5.Create().ComputeHash(content);\\n digestBase64 = Convert.ToBase64String(requestContentHash);\\n}\",\n \"language\": \"csharp\"\n },\n {\n \"code\": \"MessageDigest md = MessageDigest.getInstance(\\\"MD5\\\");\\nbyte[] thedigest = md.digest(body);\\nString digestBase64 = Base64.getEncoder().encodeToString(thedigest);\",\n \"language\": \"java\"\n },\n {\n \"code\": \"<?php\\n\\t// Ensure JSON content is encoded as UTF-8\\n\\t$json = utf8_encode($json);\\n\\t\\n\\t// Create MD5 digest ($raw_output = true)\\n\\t$md5_digest = md5($json, true);\\n\\t\\n\\t// Create Base64 digest\\n\\t$base64_digest = base64_encode($md5_digest);\\n?>\",\n \"language\": \"php\"\n }\n ]\n}\n[/block]\n2. Get the timestamp.\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"var timestampLong = (long)DateTime.UtcNow.Subtract(\\n new DateTime(1970, 01, 01, 00, 00, 00)).TotalSeconds;\\n\\nvar timestamp = timestampLong.ToString(CultureInfo.InvariantCulture);\\n\",\n \"language\": \"csharp\"\n },\n {\n \"code\": \"String timestamp = Long.toString(Math.round(System.currentTimeMillis() / 1000));\",\n \"language\": \"java\"\n },\n {\n \"code\": \"<?php\\n\\t// Get current Unix timestamp\\n\\t$timestamp = time();\\n?>\",\n \"language\": \"php\"\n }\n ]\n}\n[/block]\n3. Generate a new nonce. The nonce is a random string. In our examples we choose to generate a GUID and convert it to string.\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"var nonce = Guid.NewGuid().ToString();\",\n \"language\": \"csharp\"\n },\n {\n \"code\": \"String nonce = UUID.randomUUID().toString();\",\n \"language\": \"java\"\n },\n {\n \"code\": \"<?php\\n\\t// Create a unique nonce\\n\\t$nonce = md5(microtime(true) . $_SERVER['REMOTE_ADDR'] . rand(0, 999999));\\n?>\",\n \"language\": \"php\"\n }\n ]\n}\n[/block]\n4. Concatenate store key, method, url, timestamp, nonce, and the message digest computed in the first step.\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \" var msgToSisgn = String.Format(\\\"{0}{1}{2}{3}{4}{5}\\\",\\n storeKey,\\n method.ToUpper(),\\n url.ToLower(),\\n timestamp,\\n nonce,\\n digestBase64);\",\n \"language\": \"csharp\"\n },\n {\n \"code\": \"String msgToSisgn = new StringBuilder()\\n .append(storeKey)\\n .append(method.toUpperCase())\\n \\t\\t.append(url.toLowerCase())\\n .append(timestamp)\\n .append(nonce)\\n .append(digestBase64).toString();\",\n \"language\": \"java\"\n },\n {\n \"code\": \"<?php\\n\\t// Concatenate data\\n\\t$msg = implode('', array(\\n\\t\\t$store_key,\\n\\t\\tstrtoupper($method),\\n\\t\\tstrtolower($url),\\n\\t\\t$timestamp,\\n\\t\\t$nonce,\\n\\t\\t$json ? $base64_digest : ''\\n\\t));\\n?>\",\n \"language\": \"php\"\n }\n ]\n}\n[/block]\n5. Compute the signature by hashing the string computed in **Step 4** using HMACSHA256 and the shared secret. Convert the signature to base64 string.\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"var secretKeyByteArray = Convert.FromBase64String(sharedSecret);\\nvar requestSignatureBase64String = String.Empty;\\nusing (var hmac = new HMACSHA256(secretKeyByteArray))\\n{\\n\\tbyte[] signatureBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(msgToSign));\\n requestSignatureBase64String = Convert.ToBase64String(signatureBytes);\\n}\",\n \"language\": \"csharp\"\n },\n {\n \"code\": \"byte[] secretKey = Base64.getDecoder().decode(sharedSecret);\\nMac hmac = Mac.getInstance(\\\"HmacSHA256\\\");\\nhmac.init(new SecretKeySpec(secretKey, \\\"HmacSHA256\\\"));\\n\\nbyte[] rawHmac = hmac.doFinal(messageToSign.getBytes());\\nString signatureAsBase64 = Base64.getEncoder().encodeToString(rawHmac);\\n\",\n \"language\": \"java\"\n },\n {\n \"code\": \"<?php\\n\\t// Decode shared secret (used as a byte array)\\n\\t$byte_array = base64_decode($shared_secret);\\n\\t\\n\\t// Create signature\\n\\t$signature = base64_encode(hash_hmac('sha256', utf8_encode($msg), $byte_array, true));\\n?>\",\n \"language\": \"php\"\n }\n ]\n}\n[/block]\nAn example of a **signature** would look like:\n[block:code]\n{\n \"codes\": [\n {\n \"code\": \"WGMkdWxGZAomdNOAszTfJkuHh/KENUktabZC5y+rezk=\",\n \"language\": \"text\"\n }\n ]\n}\n[/block]\nThe [next section](doc:create-the-authorization-header) describes the format of the authorization and presents some complete examples in different programming languages,","excerpt":"","slug":"create-the-hmac-signature","type":"basic","title":"Create the HMAC signature"}