superseriousbusiness/httpsig
4
2
Fork
You've already forked httpsig
1
Golang implementation of the HTTP Signatures RFC draft, with SSH support!
Go 100%
kim 5b169288af performance and bugfixes ( #7 )
- replaces a bunch of the in-memory map[string] lookups with compile-time-generated switch cases
- marks ripemd160 as forbidden as GoLang stdlib has now marked it as deprecated
- adds a missed error check
- removes some unnecessary error checks
- removes unnecessary uses of fmt.Sprintf()
- some whitespace changes for easier reading
Reviewed-on: #7
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
2025年10月14日 13:36:00 +02:00
gen performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
algorithms.gen.go performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
algorithms.go performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
algorithms_test.go performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
digest.go performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
digest_test.go Fix hashing sum bug for digests 2019年09月24日 19:10:22 +02:00
go.mod [chore] move to code.superseriousbusiness.org ( #6 ) 2025年04月24日 20:42:52 +00:00
go.sum [chore] Update readme + mod for fork, remove CI 2024年01月19日 15:57:56 +01:00
httpsig.go performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
httpsig_test.go feat: add option to exclude query params from signature 2024年01月19日 16:01:51 +01:00
LICENSE HTTP Signature signing in golang. 2018年05月15日 23:03:43 +02:00
README.md [chore] move to code.superseriousbusiness.org ( #6 ) 2025年04月24日 20:42:52 +00:00
signing.go performance and bugfixes ( #7 ) 2025年10月14日 13:36:00 +02:00
verifying.go feat: add option to exclude query params from signature 2024年01月19日 16:01:51 +01:00

httpsig

THIS IS A FORK OF https://github.com/go-fed/httpsig, WHICH WAS NO LONGER MAINTAINED. THANK YOU TO cjslep FOR ALL YOUR HARD WORK!

HTTP Signatures made simple

go get code.superseriousbusiness.org/httpsig

Implementation of HTTP Signatures.

Supports many different combinations of MAC, HMAC signing of hash, or RSA signing of hash schemes. Its goals are:

  • Have a very simple interface for signing and validating
  • Support a variety of signing algorithms and combinations
  • Support setting either headers (Authorization or Signature)
  • Remaining flexible with headers included in the signing string
  • Support both HTTP requests and responses
  • Explicitly not support known-cryptographically weak algorithms
  • Support automatic signing and validating Digest headers

How to use

import "code.superseriousbusiness.org/httpsig"

Signing

Signing a request or response requires creating a new Signer and using it:

funcsign(privateKeycrypto.PrivateKey,pubKeyIdstring,r*http.Request)error{prefs:=[]httpsig.Algorithm{httpsig.RSA_SHA512,httpsig.RSA_SHA256}digestAlgorithm:=DigestSha256// The "Date" and "Digest" headers must already be set on r, as well as r.URL.headersToSign:=[]string{httpsig.RequestTarget,"date","digest"}signer,chosenAlgo,err:=httpsig.NewSigner(prefs,digestAlgorithm,headersToSign,httpsig.Signature)iferr!=nil{returnerr}// To sign the digest, we need to give the signer a copy of the body...// ...but it is optional, no digest will be signed if given "nil"body:=...// If r were a http.ResponseWriter, call SignResponse instead.returnsigner.SignRequest(privateKey,pubKeyId,r,body)}

Signers are not safe for concurrent use by goroutines, so be sure to guard access:

typeserverstruct{signerhttpsig.Signermu*sync.Mutex}func(s*server)handlerFunc(whttp.ResponseWriter,r*http.Request){privateKey:=...pubKeyId:=...// Set headers and such on ws.mu.Lock()defers.mu.Unlock()// To sign the digest, we need to give the signer a copy of the response body...// ...but it is optional, no digest will be signed if given "nil"body:=...err:=s.signer.SignResponse(privateKey,pubKeyId,w,body)iferr!=nil{...}...}

The pubKeyId will be used at verification time.

Verifying

Verifying requires an application to use the pubKeyId to both retrieve the key needed for verification as well as determine the algorithm to use. Use a Verifier:

funcverify(r*http.Request)error{verifier,err:=httpsig.NewVerifier(r)iferr!=nil{returnerr}pubKeyId:=verifier.KeyId()varalgohttpsig.Algorithm=...varpubKeycrypto.PublicKey=...// The verifier will verify the Digest in addition to the HTTP signaturereturnverifier.Verify(pubKey,algo)}

Verifiers are not safe for concurrent use by goroutines, but since they are constructed on a per-request or per-response basis it should not be a common restriction.