{"id":18986043,"url":"https://github.com/deanpdx/jwt-secret","last_synced_at":"2025-11-11T08:07:00.653Z","repository":{"id":255705911,"uuid":"853420283","full_name":"DeanPDX/jwt-secret","owner":"DeanPDX","description":"Quick and easy way to generate a cryptographically secure JWT signing secret","archived":false,"fork":false,"pushed_at":"2024-09-21T17:12:19.000Z","size":11,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-01T12:46:03.529Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","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/DeanPDX.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-06T16:10:47.000Z","updated_at":"2024-09-21T17:12:22.000Z","dependencies_parsed_at":"2024-09-06T20:15:02.942Z","dependency_job_id":"44e01243-aab7-4455-849d-9ed4cd8f8fa5","html_url":"https://github.com/DeanPDX/jwt-secret","commit_stats":null,"previous_names":["deanpdx/jwt-secret"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeanPDX%2Fjwt-secret","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeanPDX%2Fjwt-secret/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeanPDX%2Fjwt-secret/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DeanPDX%2Fjwt-secret/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DeanPDX","download_url":"https://codeload.github.com/DeanPDX/jwt-secret/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239994005,"owners_count":19730780,"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":[],"created_at":"2024-11-08T16:29:21.120Z","updated_at":"2025-11-11T08:06:55.607Z","avatar_url":"https://github.com/DeanPDX.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jwt-secret [![Go Reference](https://pkg.go.dev/badge/github.com/DeanPDX/jwt-secret.svg)](https://pkg.go.dev/github.com/DeanPDX/jwt-secret)\n\nThis is a utility for internal use to generate a base64-encoded cryptographically secure JWT signing secret using [crypto/rand](https://pkg.go.dev/crypto/rand).\n\n## Usage\nRun `go run github.com/DeanPDX/jwt-secret@latest` and you will see the following:\n\n```bash\nWhich signing method are you using?\n1. HS256\n2. HS384\n3. HS512\n:\n```\n\nEnter a value based on which signing algorithm you're using and you will get an appropriate key.\n\n## Why?\nSee [this issue](https://github.com/golang-jwt/jwt/issues/385) for the genesis of this utility. Specifically the quote from [RFC 7518](https://www.rfc-editor.org/rfc/rfc7518#section-3.2) about key size:\n\n\u003e    Hash-based Message Authentication Codes (HMACs) enable one to use a\n\u003e    secret plus a cryptographic hash function to generate a MAC.  This\n\u003e    can be used to demonstrate that whoever generated the MAC was in\n\u003e    possession of the MAC key.  The algorithm for implementing and\n\u003e    validating HMACs is provided in [RFC 2104](https://www.rfc-editor.org/rfc/rfc2104) [[RFC2104](https://www.rfc-editor.org/rfc/rfc2104)].\n\u003e \n\u003e    A key of the same size as the hash output (for instance, 256 bits for\n\u003e    \"HS256\") or larger MUST be used with this algorithm.  (This\n\u003e    requirement is based on [Section 5.3.4](https://www.rfc-editor.org/rfc/rfc7518#section-5.3.4) (Security Effect of the HMAC\n\u003e    Key) of NIST SP 800-117 [[NIST.800-107](https://www.rfc-editor.org/rfc/rfc7518#ref-NIST.800-107)], which states that the\n\u003e    effective security strength is the minimum of the security strength\n\u003e    of the key and two times the size of the internal hash value.)\n\nAdding to this: optimum key length is equal to block size (not greater). From [The Wikipedia Page](https://en.wikipedia.org/wiki/HMAC) pseudocode:\n\n```\n    // Keys longer than blockSize are shortened by hashing them\n    if (length(key) \u003e blockSize) then\n        key = hash(key)\n\n    // Keys shorter than blockSize are padded to blockSize by padding with zeros on the right\n    if (length(key) \u003c blockSize) then\n        return  Pad(key, blockSize) // Pad key with zeros to make it blockSize bytes long\n```\n\nSo, by matching signing secret to block size, we avoid padding with non-random numbers (zeroes) and we avoid hashing our key.\n\n## Why Base64 Encoded?\nFrom [the golang-jwt/jwt FAQ](https://golang-jwt.github.io/jwt/usage/signing_methods/#frequently-asked-questions):\n\n\u003e We often get asked why the HMAC signing method only supports []byte and not string. This is intentionally and there are different reasons for doing so. First, we aim to use the key type that the underlying cryptographic operation in the Go library uses (this also applies to the other signing methods). In case of HMAC, this is hmac.New and it uses []byte as the type to represent a key.\n\u003e \n\u003e Second, using string as a key type to represent a symmetric key can lead to unwanted situations. It gives the impression that this is something 'human readable' (like a password), but it is not. A symmetric key should contain as much entropy as possible and therefore include characters from the whole character set (even 'unreadable' ones) and ideally be generated by a cryptographic random source, such as rand.Read. Signing tokens with a cryptographically weak key will compromise the security of the tokens and in effect everything that depends on it, e.g., user authentication.\n\u003e \n\u003e If you have trouble handling a []byte key in our setup, e.g., because you are reading it from your environment variables on your cluster or similar, you can always use base64 encoding to have the key as a \"string\" type outside of your program and then use base64.Encoding.DecodeString to decode the base64 string into the []byte slice that the signing method needs.\n\nIn many projects, I am exposing my signing secrets to my APIs via secret managers as environment variables. So it makes sense to have them be base64-encoded strings. A quick cheatsheet on how to get a base64-encoded string as a byte array from an environment variable:\n\n```go\nsigningSecret, err := base64.StdEncoding.DecodeString(os.Getenv(\"MY_SIGNING_SECRET\"))\nif err != nil {\n\t// Handle error\n}\n// signingSecret is ready to use\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeanpdx%2Fjwt-secret","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeanpdx%2Fjwt-secret","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeanpdx%2Fjwt-secret/lists"}