{"id":16862824,"url":"https://github.com/ammario/isokey","last_synced_at":"2025-03-17T05:32:32.035Z","repository":{"id":57510833,"uuid":"61417883","full_name":"ammario/isokey","owner":"ammario","description":"Self-contained API keys via cryptographic signatures","archived":false,"fork":false,"pushed_at":"2017-08-25T14:32:09.000Z","size":37,"stargazers_count":121,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-27T18:27:13.933Z","etag":null,"topics":["security","symmetric-keys"],"latest_commit_sha":null,"homepage":"https://godoc.org/gopkg.in/ammario/isokey.v2","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/ammario.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":"2016-06-18T05:03:44.000Z","updated_at":"2024-01-04T16:05:36.000Z","dependencies_parsed_at":"2022-09-26T17:50:58.900Z","dependency_job_id":null,"html_url":"https://github.com/ammario/isokey","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammario%2Fisokey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammario%2Fisokey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammario%2Fisokey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammario%2Fisokey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ammario","download_url":"https://codeload.github.com/ammario/isokey/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243846984,"owners_count":20357297,"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":["security","symmetric-keys"],"created_at":"2024-10-13T14:36:55.038Z","updated_at":"2025-03-17T05:32:28.313Z","avatar_url":"https://github.com/ammario.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Isokey\n\nIsokey allows you to make and verify self-contained API keys without a database via HMAC/ECDSA signatures.\n\n## Features\n- Important information such as userID, key expire time, and flags are authenticated and stored within\nthe key.\n- Use mutliple secrets\n- Invalidate secrets and compromised keys\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n## Table Of Contents\n\n- [Symmetric Keys](#symmetric-keys)\n  - [Make a key service](#make-a-key-service)\n  - [Sign a new key](#sign-a-new-key)\n  - [Verify key](#verify-key)\n  - [Using multiple secrets](#using-multiple-secrets)\n  - [Digest Structure](#digest-structure)\n- [Asymmetric Keys](#asymmetric-keys)\n  - [Make a key pair](#make-a-key-pair)\n  - [Make key digest](#make-key-digest)\n  - [Verify key](#verify-key-1)\n  - [Digest Structure](#digest-structure-1)\n- [Invalidating keys](#invalidating-keys)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# Symmetric Keys\n\n## Make a key service\n```go\nks := NewSymKeyService([]byte(\"super_secure111\"))\n```\n\n##  Sign a new key\n```go\nkey := \u0026Key{\n\tUserID:  1,\n\tExpires: time.Now().AddDate(0, 1, 0),\n}\n\ndigest, err := ks.Sign(key)\nif err != nil {\n\tlog.Fatalf(\"Failed to sign key: %v\", err)\n}\nfmt.Printf(\"Digest is %v\\n\", digest)\n```\n\n## Verify key\n\n```go\nkey, err = ks.Verify(digest)\n\nif err != nil {\n\tlog.Fatalf(\"Failed to verify digest: %v\", err)\n}\n\n// Key authenticated\nfmt.Printf(\"Key: %+v\\n\", key)\n```\n\n## Using multiple secrets\nThe SecretVersion field is in included in the key object to enable\nimplementors to easily use multiple secrets.\n\nA secret can be decided based on any feature of a key.\n\n```go\nks.GetSecret = function(key *Key) (secret []byte){\n\tif key.SecretVersion == 1 {\n\t\treturn []byte(\"sec1\") \n\t}\n\treturn nil\n}\n```\n\n\n\n## Digest Structure\nAll binary values are big endian.\n\n| Field | Type |\n|--------|------|\n| Signature | [16]byte |\n| Made Time (Unix epoch timestamp) | uint32 |\n| Expire Time (Unix epoch timestamp) | uint32 |\n| Secret Version | uint32 |\n| User ID     | uint32 |\n| Flags | uint32 |\n\nDigests are encoded with Bitcoin's base58 alphabet.\n\nIt may seem intuitive to put the signature at the end of the digest. It's located\nat the beginning as it makes eyeballing different keys easy.\n\n# Asymmetric Keys\n\n## Make a key pair\n\nMake your private key \n`openssl ecparam -genkey -name prime256v1 -outform DER -noout -out privatekey.der`\n\nMake your public key\n`openssl ec -in privatekey.der -inform DER -outform DER -pubout -out publickey.der`\n\n\n## Make key digest\n```go\nprivKey, _ = isokey.LoadPrivateKey(\"priv.key\")\n\nks := NewAsymKeySigner(privKey)\n\nkey := \u0026Key{\n    User: 1,\n    Expires: time.Now().Add(time.Hour)\n}\n\ndigest, _ := ks.Sign(key)\n\nfmt.Printf(\"Digest: %v\", digest)\n```\n\n##  Verify key\n```go\npubKey, err := isokey.LoadPublicKey(\"pub.key\")\nif err != nil {\n\tlog.Fatalf(\"Failed to load pubkey: %v\", err)\n}\n\nkv := NewAsymKeyVerifier(pubKey)\n\nkey, err := kv.Verify(digest)\nif err != nil {\n\tlog.Fatalf(\"Failed to verify key: %v\", err)\n}\n\nfmt.Printf(\"Key verified %+v\\n\", key)\n\n```\n\n\n## Digest Structure\nAll binary values are big endian.\n\n| Field | Type |\n|--------|------|\n| R len     | uint8\n| R         | []byte\n| S Len     | uint8\n| S         | []byte\n| Made Time (Unix epoch timestamp) | uint32 |\n| Expire Time (Unix epoch timestamp) | uint32 |\n| Secret Version | uint32 |\n| User ID     | uint32 |\n| Flags | uint32 |\n\nDigests are encoded with Bitcoin's base58 alphabet.\n\n\n# Invalidating keys\n\nExpired keys always fail to validate.\n\nYou can add custom invalidation logic via the `Invalidator` field of verifiers.\n\n```go\nverifier.Invalidator = function(key *isokey.Key) bool {\n    // reject keys made before some time\n    if key.UserID == 10 \u0026\u0026 key.Made.Before(time.Date(2015, time.November, 10, 23, 0, 0, 0, time.UTC)) {\n        return true\n    }\n    return false\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fammario%2Fisokey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fammario%2Fisokey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fammario%2Fisokey/lists"}