jose-jwt: JSON Object Signing and Encryption Library

[ bsd3, cryptography, json ] [ Propose Tags ]

An implementation of the JOSE suite of IETF standards and the closely related JWT (JSON web token) spec (

Both signed and encrypted JWTs are supported, as well as simple JWK keys.

[Skip to Readme]
Versions [faq] 0.1, 0.2, 0.3, 0.3.1, 0.4, 0.4.1,, 0.4.2, 0.5, 0.6, 0.6.1, 0.6.2, 0.7, 0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.7.5, 0.7.6, 0.7.7, 0.7.8, 0.8.0, 0.9.0, 0.9.1, 0.9.2
Change log
Dependencies aeson (>=, attoparsec (>=, base (>=4.9 && <5), bytestring (>=0.9), cereal (>=0.4), containers (>=0.4), cryptonite (>=0.19), memory (>=0.10), mtl (>=, text (>=0.11), time (>=1.4), transformers (>=0.3), transformers-compat (>=0.4), unordered-containers (>=0.2), vector (>=0.10) [details]
License BSD-3-Clause
Author Luke Taylor <>
Maintainer Luke Taylor <>
Category JSON, Cryptography
Home page
Bug tracker
Source repo head: git clone
Uploaded by LukeTaylor at 2021-03-15T00:20:14Z
Distributions LTSHaskell:0.8.0, NixOS:0.9.2, Stackage:0.9.2
Downloads 19234 total (112 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2021-03-15 [all 1 reports]


[Index] [Quick Jump]



Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info


Maintainer's Corner

For package maintainers and hackage trustees

Readme for jose-jwt-0.9.1

[back to package description]


A Haskell implementation of the JSON Object Signing and Encryption (JOSE) specifications and the related JWT specification, as used, for example, in OpenID Connect.


The JWT specification was split into JWS and JWE during its development and thus does not contain much. Basically, a JWT is either a JWS or a JWE depending on whether it is signed or encrypted. It is encoded as a sequence of base64 strings separated by '.' characters [1].

Technically, the content of a JWT should be JSON (unless it's a nested JWT), but the library doesn't care - it only requires a bytestring. The calling application should verify that the content is valid. Exactly what that means will depend on what you are using JWTs for.


You can either use the high-level encode and decode functions in the Jwt module or specific functions in the Jws and Jwe modules.

The following examples can be entered directly into ghci. Use

> :set -XOverloadedStrings

to begin with.

JWS signing example with a symmetric HMAC algorithm

HMAC is a good choice when both signer and verifier have a copy of the key.

> import Jose.Jws (hmacEncode, hmacDecode)
> import Jose.Jwa (JwsAlg(HS256))
> hmacEncode HS256 "aRANDOMlygeneratedkey" "my JSON message"
Right (Jwt {unJwt = "eyJhbGciOiJIUzI1NiJ9.bXkgSlNPTiBtZXNzYWdl.lTJx7ECLwYF3P7WbrrUpcp_2SdLiFXaDwK-PXcipt5Q"})
> hmacDecode "aRANDOMlygeneratedkey" "eyJhbGciOiJIUzI1NiJ9.bXkgSlNPTiBtZXNzYWdl.lTJx7ECLwYF3P7WbrrUpcp_2SdLiFXaDwK-PXcipt5Q"
Right (JwsHeader {jwsAlg = HS256, jwsTyp = Nothing, jwsCty = Nothing, jwsKid = Nothing},"my JSON message")

Trying to decode with a different key would return a Left BadSignature [2].

JWS signing using Ed25519 private key

Some situations require the use of public key cryptography for signing. For example, only a trusted party is allowed to create a signed token, but it must be verified by others.

Elliptic-curve EdDSA signing and verification are supported as defined in RFC 8037, as well as the older RSA JWS algorithms.

> import Jose.Jwt
> import Jose.Jwk
> import Jose.Jwa (JwsAlg(EdDSA))
> import Data.ByteString (ByteString)
> import Data.Aeson (decodeStrict)
> jsonJwk = "{\"kty\":\"OKP\", \"crv\":\"Ed25519\", \"d\":\"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A\", \"x\":\"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo\"}" :: ByteString
> Just jwk = decodeStrict jsonJwk :: Maybe Jwk
> Jose.Jwt.encode [jwk] (JwsEncoding EdDSA) (Claims "public claims")
Right (Jwt {unJwt = "eyJhbGciOiJFZERTQSJ9.cHVibGljIGNsYWltcw.xYekeeGSQVpnQbl16lOCqFcmYsUj3goSTrZ4UBQqogjHLrvFUaVJ_StBqly-Tb-0xvayjUMM4INYBTwFMt_xAQ"})

To verify the JWT you would use the Jose.Jwt.decode function with the corresponding public key.

More examples can be found in the package documentation.

Build Status

Build Status

[1] This is now referred to as "compact serialization". The additional "JSON serialization" is not supported in this library.

[2] Note that a real key for HMAC256 should be a much longer, random string of bytes. See, for example, this stackexchange answer.