diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.9.1
+-----
+
+* Fix for tests broken due to [different aeson key ordering](https://github.com/commercialhaskell/stackage/issues/5878).
+
 0.9.0
 -----
 
@@ -6,8 +11,7 @@
 0.8.0
 -----
 
-* The result of the `Jose.Jwt.decodeClaims` function is now polymorphic so it can be used with
-any `FromJSON` type.
+* The result of the `Jose.Jwt.decodeClaims` function is now polymorphic so it can be used with any `FromJSON` type.
 * Only ghc 8 upwards are now supported.
 * the RSA-OAEP-256 algorithm is now supported.
 
diff --git a/Jose/Jwe.hs b/Jose/Jwe.hs
--- a/Jose/Jwe.hs
+++ b/Jose/Jwe.hs
@@ -12,20 +12,20 @@
 -- of the token need to have a copy of the key, which they must keep secret. With
 -- RSA anyone can send you a JWE if they have a copy of your public key.
 --
--- In the example below, we show encoding and decoding using a 512 byte RSA key pair
--- (in practice you would use a larger key-size, for example 2048 bytes):
+-- In the example below, we show encoding and decoding using a 2048 bit RSA key pair
+-- (256 bytes).
 --
 -- >>> import Jose.Jwe
 -- >>> import Jose.Jwa
 -- >>> import Jose.Jwk (generateRsaKeyPair, generateSymmetricKey, KeyUse(Enc), KeyId)
--- >>> (kPub, kPr) <- generateRsaKeyPair 512 (KeyId "My RSA Key") Enc Nothing
+-- >>> (kPub, kPr) <- generateRsaKeyPair 256 (KeyId "My RSA Key") Enc Nothing
 -- >>> Right (Jwt jwt) <- jwkEncode RSA_OAEP A128GCM kPub (Claims "secret claims")
 -- >>> Right (Jwe (hdr, claims)) <- jwkDecode kPr jwt
 -- >>> claims
 -- "secret claims"
 --
 -- Using 128-bit AES keywrap is very similar, the main difference is that
--- we generate a 128-bit symmetric key:
+-- we generate a 128-bit symmetric key (16 bytes):
 --
 -- >>> aesKey <- generateSymmetricKey 16 (KeyId "My Keywrap Key") Enc Nothing
 -- >>> Right (Jwt jwt) <- jwkEncode A128KW A128GCM aesKey (Claims "more secret claims")
@@ -46,10 +46,13 @@
 import Crypto.Cipher.Types (AuthTag(..))
 import Crypto.PubKey.RSA (PrivateKey(..), PublicKey(..), generateBlinder, private_pub)
 import Crypto.Random (MonadRandom)
+import qualified Data.Aeson as A
 import Data.ByteArray (ByteArray, ScrubbedBytes)
 import qualified Data.ByteArray as BA
 import Data.ByteString (ByteString)
 import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as BL
+import Data.Maybe (isNothing)
 import Jose.Types
 import qualified Jose.Internal.Base64 as B64
 import Jose.Internal.Crypto
@@ -67,13 +70,24 @@
     -> Payload                         -- ^ The token content (claims or nested JWT)
     -> m (Either JwtError Jwt)         -- ^ The encoded JWE if successful
 jwkEncode a e jwk payload = runExceptT $ case jwk of
-    RsaPublicJwk kPub kid _ _ -> doEncode (hdr kid) (doRsa kPub) bytes
-    RsaPrivateJwk kPr kid _ _ -> doEncode (hdr kid) (doRsa (private_pub kPr)) bytes
-    SymmetricJwk  kek kid _ _ -> doEncode (hdr kid) (ExceptT .  return . keyWrap a (BA.convert kek)) bytes
+    RsaPublicJwk kPub kid _ _ -> doEncode (hdr kid) e (doRsa kPub) bytes
+    RsaPrivateJwk kPr kid _ _ -> doEncode (hdr kid) e (doRsa (private_pub kPr)) bytes
+    SymmetricJwk  kek kid _ _ -> doEncode (hdr kid) e (ExceptT .  return . keyWrap a (BA.convert kek)) bytes
     _                         -> throwE $ KeyError "JWK cannot encode a JWE"
   where
     doRsa kPub = ExceptT . rsaEncrypt kPub a
-    hdr kid = defJweHdr {jweAlg = a, jweEnc = e, jweKid = kid, jweCty = contentType}
+    hdr :: Maybe KeyId -> B.ByteString
+    hdr kid = BL.toStrict $
+        BL.concat
+            [ "{\"alg\":"
+            , A.encode a
+            , ",\"enc\":"
+            , A.encode e
+            , maybe "" (\c -> BL.concat [",\"cty\":\"", c, "\"" ]) contentType
+            , if isNothing kid then "" else BL.concat [",\"kid\":", A.encode kid ]
+            , "}"
+            ]
+
     (contentType, bytes) = case payload of
         Claims c       -> (Nothing, c)
         Nested (Jwt b) -> (Just "JWT", b)
@@ -117,19 +131,18 @@
 
 
 doEncode :: (MonadRandom m, ByteArray ba)
-    => JweHeader
+    => ByteString
+    -> Enc
     -> (ScrubbedBytes -> ExceptT JwtError m ByteString)
     -> ba
     -> ExceptT JwtError m Jwt
-doEncode h encryptKey claims = do
+doEncode hdr e encryptKey claims = do
     (cmk, iv) <- lift (generateCmkAndIV e)
     let Just (AuthTag sig, ct) = encryptPayload e cmk iv aad claims
     jweKey <- encryptKey cmk
     let jwe = B.intercalate "." $ map B64.encode [hdr, jweKey, BA.convert iv, BA.convert ct, BA.convert sig]
     return (Jwt jwe)
   where
-    e   = jweEnc h
-    hdr = encodeHeader h
     aad = B64.encode hdr
 
 -- | Creates a JWE with the content key encoded using RSA.
@@ -139,7 +152,9 @@
     -> PublicKey       -- ^ RSA key to encrypt with
     -> ByteString      -- ^ The JWT claims (content)
     -> m (Either JwtError Jwt) -- ^ The encoded JWE
-rsaEncode a e kPub claims = runExceptT $ doEncode (defJweHdr {jweAlg = a, jweEnc = e}) (ExceptT . rsaEncrypt kPub a) claims
+rsaEncode a e kPub claims = runExceptT $ doEncode hdr e (ExceptT . rsaEncrypt kPub a) claims
+  where
+    hdr = BL.toStrict $ BL.concat ["{\"alg\":", A.encode a, ",", "\"enc\":", A.encode e, "}"]
 
 
 -- | Decrypts a JWE.
diff --git a/jose-jwt.cabal b/jose-jwt.cabal
--- a/jose-jwt.cabal
+++ b/jose-jwt.cabal
@@ -1,5 +1,5 @@
 Name:               jose-jwt
-Version:            0.9.0
+Version:            0.9.1
 Synopsis:           JSON Object Signing and Encryption Library
 Homepage:           http://github.com/tekul/jose-jwt
 Bug-Reports:        http://github.com/tekul/jose-jwt/issues
diff --git a/tests/Tests/JweSpec.hs b/tests/Tests/JweSpec.hs
--- a/tests/Tests/JweSpec.hs
+++ b/tests/Tests/JweSpec.hs
@@ -5,11 +5,12 @@
 module Tests.JweSpec where
 
 import Control.Applicative
-import Data.Aeson (decodeStrict')
+import Data.Aeson (decodeStrict', ToJSON)
 import Data.Bits (xor)
 import Data.Word (Word8, Word64)
 import qualified Data.ByteArray as BA
 import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as BL
 import qualified Data.ByteString.Char8 as BC
 import Test.Hspec
 import Test.HUnit hiding (Test)
@@ -48,7 +49,7 @@
             (rsaEncrypt a1PubKey RSA_OAEP a1cek) @?= (Right a1jweKey, RNG "")
 
       it "encrypts the payload to the expected ciphertext and authentication tag" $ do
-        let aad = B64.encode . encodeHeader $ a1Header
+        let aad = B64.encode ("{\"alg\":\"RSA-OAEP\",\"enc\":\"A256GCM\"}" :: B.ByteString)
         encryptPayload A256GCM a1cek a1iv aad a1Payload @?= Just (AuthTag a1Tag, a1Ciphertext)
 
       it "encodes the payload to the expected JWT, leaving the RNG empty" $
@@ -94,7 +95,7 @@
 
     context "when using JWE Appendix 2 data" $ do
       let a2Header = defJweHdr {jweAlg = RSA1_5, jweEnc = A128CBC_HS256}
-      let aad = B64.encode . encodeHeader $ a2Header
+      let aad = B64.encode ("{\"alg\":\"RSA1_5\",\"enc\":\"A128CBC-HS256\"}" :: B.ByteString)
 
       it "generates the expected RSA-encrypted content key" $
         withDRG (RNG a2seed) (rsaEncrypt a2PubKey RSA1_5 a2cek) @?= (Right a2jweKey, RNG "")
@@ -130,7 +131,7 @@
     context "when using JWE Appendix 3 data" $ do
       let Just jwk = decodeStrict' a3jwk
           a3Header = defJweHdr {jweAlg = A128KW, jweEnc = A128CBC_HS256}
-      it "encodes the payload to the epected JWT" $
+      it "encodes the payload to the expected JWT" $
         withDRG (RNG $ B.concat [a3cek, a3iv])
             (Jwe.jwkEncode A128KW A128CBC_HS256 jwk (Claims a3Payload)) @?= (Right (Jwt a3), RNG "")
 
@@ -159,7 +160,7 @@
 
 -- verboseQuickCheckWith quickCheckWith stdArgs {maxSuccess=10000}  jweRoundTrip
 jweRoundTrip :: RNG -> JWEAlgs -> [Word8] -> Bool
-jweRoundTrip g (JWEAlgs a e) msg = encodeDecode == Right (Jwe (defJweHdr {jweAlg = a, jweEnc = e}, bs))
+jweRoundTrip g (JWEAlgs a e) msg = encodeDecode == Right (Jwe (defJweHdr {jweAlg = a, jweEnc = e }, bs))
   where
     jwks = [a1jwk, a2jwk, a3jwk, aes192jwk, aes256jwk] >>= \j -> let Just jwk = decodeStrict' j in [jwk]
     bs = B.pack msg
