{"id":21826434,"url":"https://github.com/shopstack-projects/shopstack-security-hmac","last_synced_at":"2025-10-08T04:31:02.814Z","repository":{"id":47411114,"uuid":"386581166","full_name":"shopstack-projects/shopstack-security-hmac","owner":"shopstack-projects","description":"Authenticate Shopify requests using the provided HMAC.","archived":false,"fork":false,"pushed_at":"2022-08-29T13:24:44.000Z","size":87,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-04T18:48:07.509Z","etag":null,"topics":["authentication","hmac","security","shopify","shopify-apps"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shopstack-projects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-16T09:25:03.000Z","updated_at":"2024-06-16T14:01:55.000Z","dependencies_parsed_at":"2022-08-23T09:20:27.179Z","dependency_job_id":null,"html_url":"https://github.com/shopstack-projects/shopstack-security-hmac","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shopstack-projects%2Fshopstack-security-hmac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shopstack-projects%2Fshopstack-security-hmac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shopstack-projects%2Fshopstack-security-hmac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shopstack-projects%2Fshopstack-security-hmac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shopstack-projects","download_url":"https://codeload.github.com/shopstack-projects/shopstack-security-hmac/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235679180,"owners_count":19028323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","hmac","security","shopify","shopify-apps"],"created_at":"2024-11-27T18:04:08.562Z","updated_at":"2025-10-08T04:30:57.506Z","avatar_url":"https://github.com/shopstack-projects.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shopstack Security HMAC\n\nAuthenticate Shopify HTTP [requests](https://shopify.dev/apps/auth/oauth#verification) and\n[webhooks](https://shopify.dev/apps/webhooks#6-verify-a-webhook), by validating the message against the provided HMAC\ncode. \n\n[![Build](https://github.com/shopstack-projects/shopstack-security-hmac/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/shopstack-projects/shopstack-security-hmac/actions/workflows/build.yml?query=branch%3Amain)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/4b15e3f1c123432eb7d274bcc083b199)](https://www.codacy.com/gh/shopstack-projects/shopstack-security-hmac/dashboard?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=shopstack-projects/shopstack-security-hmac\u0026amp;utm_campaign=Badge_Grade)\n[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/4b15e3f1c123432eb7d274bcc083b199)](https://www.codacy.com/gh/shopstack-projects/shopstack-security-hmac/dashboard?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=shopstack-projects/shopstack-security-hmac\u0026utm_campaign=Badge_Coverage)\n\n## Getting Started\n\nProject artifacts can be downloaded from the [Maven Central Repository](https://search.maven.org/artifact/dev.shopstack.security/shopstack-security-hmac).\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003edev.shopstack.security\u003c/groupId\u003e\n    \u003cartifactId\u003eshopstack-security-hmac\u003c/artifactId\u003e\n    \u003cversion\u003e1.2.0.RELEASE\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### SLF4J\n\nThis library uses the SLF4J API module without an implementation library, to keep our artifact size small.\nYou should include an SLF4J compatible logger implementation in your project.\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n    \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\n## Usage\n\n### Verify a HMAC\n\nUse the `HmacVerifier` to authenticate a Shopify request by evaluating the provided HMAC code against the message body.\n\nShopify HTTP requests and redirects may include the HMAC code in either a `X-Shopify-Hmac-Sha256` HTTP header or in a\n`hmac` query parameter.\n\nThe message to use when generating a comparison HMAC will either consist of the HTTP request body (for POST requests),\nor the request's query parameters (for GET requests).\n\n#### Scenario 1 - Using the HTTP Body\n\n```java\nString secret = System.getenv(\"SHOPIFY_SHARED_SECRET\");\nString hmac = httpRequest.getHeader(\"X-Shopify-Hmac-Sha256\");\n\nString message = httpRequest.getBody();\n\n// Verify the request using the HMAC and message.\nboolean result = new HmacVerifier(secret).apply(hmac, message);\n\nif (!result) {\n    // Shopify message could not be verified.\n}\n```\n\n#### Scenario 2 - Using HTTP Query Parameters\n\nWhen using query parameters, be sure to first [remove the `hmac` query parameter](https://shopify.dev/apps/auth/oauth#remove-the-hmac).\n\n```java\nString secret = System.getenv(\"SHOPIFY_SHARED_SECRET\");\n\nMap\u003cString, String\u003e queryParameters = httpRequest.getQueryParameters();\n\nString hmac = queryParameters.get(\"hmac\");\n    \nString message = queryParameters.keySet().stream()\n    .filter(key -\u003e !key.equalsIgnoreCase(\"hmac\"))\n    .map(key -\u003e key + \"=\" + queryParameters.get(key))\n    .sorted() // Lexicographic order is required.\n    .collect(joining(\"\u0026\"));\n\n// Verify the request using the HMAC and message.\nboolean result = new HmacVerifier(secret).apply(hmac, message);\n\nif (!result) {\n    // Shopify message could not be verified.\n}\n```\n\n#### Scenario 3 - Using a Base16 (Hexadecimal) Encoding\n\nShopify encodes the HMAC value in Base16 (Hexadecimal) for requests used when granting permissions to an application.\nYou can configure the data encoding when creating the `HmacVerifier`.\n\nWe default to using a Base64 encoding otherwise, which is suitable for other Shopify requests.\n\n```java\nString secret = System.getenv(\"SHOPIFY_SHARED_SECRET\");\n\nMap\u003cString, String\u003e queryParameters = httpRequest.getQueryParameters();\n\nString hmac = queryParameters.get(\"hmac\");\n\nString message = queryParameters.keySet().stream()\n    .filter(key -\u003e !key.equalsIgnoreCase(\"hmac\"))\n    .map(key -\u003e key + \"=\" + queryParameters.get(key))\n    .sorted() // Lexicographic order is required.\n    .collect(joining(\"\u0026\"));\n\n// Verify the request using the HMAC and message.\nboolean result = new HmacVerifier(secret, Encoding.BASE16) // Specify a Base16 encoding as required.\n    .apply(hmac, message);\n\nif (!result) {\n    // Shopify message could not be verified.\n}\n```\n\n### Generate a HMAC\n\nYou can also generate a HMAC code directly using the `HmacGenerator`.\n\n```java\nString secret = System.getenv(\"SHOPIFY_SHARED_SECRET\");\nString message = \"Hello world\";\n\nString hmac = new HmacGenerator(secret).apply(message);\n```\n\n## Building from Source\n\nYou don't need to build from source, but if you want to try it out, you can use the included Gradle wrapper.\nYou will also need JDK 11.\n\n```shell\n$ ./gradlew clean test build --info\n```\n\n## License\n\nDistributed under the MIT License. See `LICENSE` for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshopstack-projects%2Fshopstack-security-hmac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshopstack-projects%2Fshopstack-security-hmac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshopstack-projects%2Fshopstack-security-hmac/lists"}