JOSE for Go

github.com/malcolmston/jose

The whole JOSE stack — JWS, JWE, JWK, JWA — on the standard library alone.

 GitHubports panva/jose

The complement to this family's <b>jwt</b> port: where jwt covers RFC 7519 claims over the JWS compact serialization, jose implements the rest of the stack — JWS (RFC 7515) including the general and flattened JSON serializations with multiple signatures, JWE (RFC 7516) encryption with multiple recipients, JWK and JWK Sets (RFC 7517), and the JWA algorithm registry (RFC 7518). Because the family rule is standard library only, <code>golang.org/x/crypto</code> is off-limits, so AES Key Wrap (RFC 3394), PBKDF2 (RFC 8018) and the Concat KDF (NIST SP 800-56A) are implemented here and verified against their own specification vectors. Measured against the RFC 7520 cookbook — the worked examples the JOSE working group published precisely so implementations could prove themselves. The import path is github.com/malcolmston/jose.

Install

shell
$ go get github.com/malcolmston/jose

Quick start

main.go
import "github.com/malcolmston/jose"

signed, _ := jose.Sign([]byte("payload"), privateKey,
    jose.SignOptions{Algorithm: "ES256"})
payload, header, _ := jose.Verify(signed, publicKey)

token, _ := jose.Encrypt([]byte("secret"), publicKey,
    jose.EncryptOptions{
        Algorithm:  "ECDH-ES+A128KW",
        Encryption: "A128GCM",
    })
plaintext, header, _ := jose.Decrypt(token, privateKey)

Features

  • JWSSign / Verify for compact, SignJSON / VerifyJSON for the general and flattened JSON serializations, and SignJSONMulti for multiple signatures over one payload
  • JWEEncrypt / Decrypt compact, plus EncryptJSON, EncryptJSONMulti and DecryptJSON for multi-recipient JSON serialization with per-recipient headers and the aad member
  • Key management — RSA-OAEP and RSA-OAEP-256, A128/192/256KW, dir, ECDH-ES and ECDH-ES+AxxxKW, A128/192/256GCMKW, and PBES2-HS256/384/512
  • Content encryption — A128/192/256CBC-HS256/384/512 (encrypt-then-MAC, constant-time tags) and A128/192/256GCM
  • JWK / JWKSParseJWK, ParseJWKSet, FromKey, Public, LookupKeyID, and RFC 7638 Thumbprint, covering RSA, EC, OKP (Ed25519/X25519) and oct keys
  • RFC 8037 CFRG curves — EdDSA signing with Ed25519 (deterministic, so signatures reproduce byte for byte) and ECDH-ES over X25519
  • RFC 7797 unencoded payload (b64:false) with the accompanying crit handling
  • Primitives written here because the stdlib does not ship them — AES Key Wrap (RFC 3394), PBKDF2 (RFC 8018) and Concat KDF (SP 800-56A), each verified against its own published vectors
  • Hardened by construction — every algorithm type-asserts its key to close algorithm confusion, none is never verifiable, unknown crit parameters are rejected, zip:DEF decompression is bounded against DEFLATE bombs, PBES2 iteration counts are capped, and CBC verifies the tag before touching ciphertext so there is no padding oracle
  • Zero dependencies — pure Go standard library (crypto/*, compress/flate, encoding/*), no cgo
JOSE