{"id":17435667,"url":"https://github.com/denpeshkov/httpsign","last_synced_at":"2025-12-15T02:07:55.371Z","repository":{"id":257813121,"uuid":"868367603","full_name":"denpeshkov/httpsign","owner":"denpeshkov","description":"Signatures for HTTP requests","archived":false,"fork":false,"pushed_at":"2024-11-15T12:49:48.000Z","size":14,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T04:42:15.946Z","etag":null,"topics":["cryptography","go","golang","http","signature"],"latest_commit_sha":null,"homepage":"","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/denpeshkov.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,"zenodo":null}},"created_at":"2024-10-06T07:42:15.000Z","updated_at":"2025-02-25T18:06:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"024660ac-2c8c-48f8-ba0a-51d8779d19fd","html_url":"https://github.com/denpeshkov/httpsign","commit_stats":null,"previous_names":["denpeshkov/httpsig"],"tags_count":1,"template":false,"template_full_name":"denpeshkov/go-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denpeshkov%2Fhttpsign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denpeshkov%2Fhttpsign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denpeshkov%2Fhttpsign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denpeshkov%2Fhttpsign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denpeshkov","download_url":"https://codeload.github.com/denpeshkov/httpsign/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249191152,"owners_count":21227508,"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":["cryptography","go","golang","http","signature"],"created_at":"2024-10-17T10:00:59.451Z","updated_at":"2025-12-15T02:07:50.079Z","avatar_url":"https://github.com/denpeshkov.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# httpsign\n\n[![CI](https://github.com/denpeshkov/httpsign/actions/workflows/ci.yml/badge.svg)](https://github.com/denpeshkov/httpsign/actions/workflows/ci.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/denpeshkov/httpsign.svg)](https://pkg.go.dev/github.com/denpeshkov/httpsign)\n\n`httpsign` provides utilities for creating, encoding, and verifying signatures within HTTP requests. Library provides both the transport to create digital signatures or message authentication codes (MACs), and a middleware to verify such signatures.\n\n# Overview\n\nThe library provides the following signature algorithms:\n\n- [HMAC](https://pkg.go.dev/github.com/denpeshkov/httpsign/hmac)\n- [RSA](https://pkg.go.dev/github.com/denpeshkov/httpsign/rsa)\n- [ECDSA](https://pkg.go.dev/github.com/denpeshkov/httpsign/ecdsa)\n- [Ed25519](https://pkg.go.dev/github.com/denpeshkov/httpsign/ed25519)\n\nThe API is based on four interfaces: `Signer`, `Verifier` and `SignerSource`, `VerifierSource`.\n\n`Signer` is essentially a wrapper around the signature algorithm's private key.\nBecause the private key also contains the corresponding public key, `Signer` can be used for verification as well.\n`SignerSource` abstracts the retrieval of `Signer` based on the provided key ID.\n\n`Verifier` uses the public key for verification. It is useful in situations where the user only has access to the public key and not the private key.\n`VerifierSource` abstracts the retrieval of `Verifier` based on the provided key ID.\n\nThe HMAC algorithm is an exception, as it uses the same shared secret key for both signing and verification.\nTherefore, the API provides a single structure, [`HMAC`](https://pkg.go.dev/github.com/denpeshkov/httpsign/hmac#HMAC), for both signing and verification.\n\n# Usage\n\nHere is an example using `HMAC-SHA-256` algorithm:\n\n```go\ntype staticSource struct{ h *hmac.HMAC }\n\nfunc (s staticSource) Signer(ctx context.Context, kid string) (Signer, error) {\n\treturn s.h, nil\n}\nfunc (s staticSource) Verifier(ctx context.Context, kid string) (Verifier, error) {\n\treturn s.h, nil\n}\n\nconst (\n\tsecret = \"shared-secret\"\n\tkid    = \"key-id\"\n)\n\n// Create the signer using the shared secret key.\nsgn, err := hmac.New([]byte(secret), crypto.SHA256)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Create the source given the signer.\nsrc := staticSource{sgn}\n\n// Create the Transport.\ntr := NewTransport(src, kid)\n\n// Create an HTTP client using our transport to sign outgoing requests.\nc := \u0026http.Client{Transport: tr}\n\n// Create the Middleware to verify incoming requests signatures.\nm := Middleware(src, DefaultErrorHandler)\n\n// Wrap the handler.\nvar handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello\")\n})\nhandler = m(handler)\n\nhttp.Handle(\"/api/foo\", handler)\n```\n\nHere is an example using `RSASSA-PKCS1-v1.5 SHA-256` algorithm:\n\n```go\ntype staticSource struct{ h *rsa.PKCSSigner }\n\nfunc (s staticSource) Signer(ctx context.Context, kid string) (Signer, error) {\n\treturn s.h, nil\n}\nfunc (s staticSource) Verifier(ctx context.Context, kid string) (Verifier, error) {\n\treturn s.h, nil\n}\n\nconst kid = \"key-id\"\n\nprivateKey, err := stdrsa.GenerateKey(rand.Reader, 2048)\nhash := crypto.SHA256\n\n// Create the signer using the shared secret key.\nsgn, err := rsa.NewPKCSSigner(privateKey, hash)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Create the source given the signer.\nsrc := staticSource{sgn}\n\n// Create the Transport.\ntr := NewTransport(src, kid)\n\n// Create an HTTP client using our transport to sign outgoing requests.\nc := \u0026http.Client{Transport: tr}\n\n// Create the Middleware to verify incoming requests signatures.\nm := Middleware(src, DefaultErrorHandler)\n\n// Alternatively, we can explicitly create a Verifier using the public key.\nvrf, err := hsrsa.NewPKCSVerifier(\u0026privateKey.PublicKey, hash)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Wrap the handler.\nvar handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello\")\n})\nhandler = m(handler)\n\nhttp.Handle(\"/api/foo\", handler)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenpeshkov%2Fhttpsign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenpeshkov%2Fhttpsign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenpeshkov%2Fhttpsign/lists"}