diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.9.2
+-----
+
+* Add `UnsupportedJwt` constructor to `Jwk` type which wraps the JSON value. This prevents failure loading keys which have `alg` or `kty` values which we don't support (see #31).
+
 0.9.1
 -----
 
diff --git a/Jose/Internal/Crypto.hs b/Jose/Internal/Crypto.hs
--- a/Jose/Internal/Crypto.hs
+++ b/Jose/Internal/Crypto.hs
@@ -26,7 +26,6 @@
 where
 
 
-import           Control.Applicative
 import           Control.Monad (when, unless)
 import           Crypto.Error
 import           Crypto.Cipher.AES
diff --git a/Jose/Internal/Parser.hs b/Jose/Internal/Parser.hs
--- a/Jose/Internal/Parser.hs
+++ b/Jose/Internal/Parser.hs
@@ -16,7 +16,6 @@
     )
 where
 
-import           Control.Applicative
 import           Data.Bifunctor (first)
 import Data.Aeson (eitherDecodeStrict')
 import           Data.Attoparsec.ByteString (Parser)
diff --git a/Jose/Jwa.hs b/Jose/Jwa.hs
--- a/Jose/Jwa.hs
+++ b/Jose/Jwa.hs
@@ -10,7 +10,6 @@
     )
 where
 
-import Control.Applicative (pure)
 import Data.Aeson
 import Data.Text (Text)
 import Data.Tuple (swap)
diff --git a/Jose/Jwe.hs b/Jose/Jwe.hs
--- a/Jose/Jwe.hs
+++ b/Jose/Jwe.hs
@@ -13,7 +13,8 @@
 -- 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 2048 bit RSA key pair
--- (256 bytes).
+-- (256 bytes). If using RSA, use one of the @RSA_OAEP@ algorithms. @RSA1_5@ is
+-- deprecated due to <https://robotattack.org/ known vulnerabilities>.
 --
 -- >>> import Jose.Jwe
 -- >>> import Jose.Jwa
@@ -106,7 +107,8 @@
         e <- doDecode (rsaDecrypt (Just blinder) kPr) jwt
         return (Jwe e)
     SymmetricJwk kb   _ _ _ -> fmap Jwe (doDecode (keyUnwrap (BA.convert kb)) jwt)
-    _                       -> throwE $ KeyError "JWK cannot decode a JWE"
+    UnsupportedJwk _ -> throwE (KeyError "Unsupported JWK cannot be used to decode JWE")
+    _ -> throwE $ KeyError "This JWK cannot decode a JWE"
 
 
 doDecode :: MonadRandom m
diff --git a/Jose/Jwk.hs b/Jose/Jwk.hs
--- a/Jose/Jwk.hs
+++ b/Jose/Jwk.hs
@@ -20,7 +20,6 @@
     )
 where
 
-import           Control.Applicative (pure)
 import           Control.Monad (unless)
 import           Crypto.Error (CryptoFailable(..))
 import           Crypto.Random (MonadRandom, getRandomBytes)
@@ -30,12 +29,13 @@
 import qualified Crypto.PubKey.Ed448 as Ed448
 import qualified Crypto.PubKey.ECC.Types as ECC
 import           Crypto.Number.Serialize
-import           Data.Aeson (genericToJSON, Value(..), FromJSON(..), ToJSON(..), withText)
+import           Data.Aeson (fromJSON, genericToJSON, Object, Result(..), Value(..), FromJSON(..), ToJSON(..), withText)
 import           Data.Aeson.Types (Parser, Options (..), defaultOptions)
 import qualified Data.ByteArray as BA
 import           Data.ByteString (ByteString)
 import qualified Data.ByteString as B
-import           Data.Maybe (isNothing)
+import qualified Data.HashMap.Strict as H
+import           Data.Maybe (isNothing, fromMaybe)
 import           Data.Text (Text)
 import qualified Data.Text.Encoding as TE
 import           GHC.Generics (Generic)
@@ -68,9 +68,10 @@
          | Ed448PrivateJwk !Ed448.SecretKey !Ed448.PublicKey !(Maybe KeyId)
          | Ed448PublicJwk !Ed448.PublicKey !(Maybe KeyId)
          | SymmetricJwk  !ByteString      !(Maybe KeyId) !(Maybe KeyUse) !(Maybe Alg)
+         | UnsupportedJwk Object
            deriving (Show, Eq)
 
-data JwkSet = JwkSet
+newtype JwkSet = JwkSet
     { keys :: [Jwk]
     } deriving (Show, Eq, Generic)
 
@@ -208,30 +209,33 @@
     EcPublicJwk   _ keyId _ _ _ -> keyId
     EcPrivateJwk  _ keyId _ _ _ -> keyId
     SymmetricJwk  _ keyId _ _ -> keyId
+    UnsupportedJwk _ -> Nothing
 
 jwkUse :: Jwk -> Maybe KeyUse
 jwkUse key = case key of
-    Ed25519PrivateJwk _ _ _ -> Just Sig
+    Ed25519PrivateJwk {} -> Just Sig
     Ed25519PublicJwk _ _ -> Just Sig
-    Ed448PrivateJwk _ _ _ -> Just Sig
+    Ed448PrivateJwk {} -> Just Sig
     Ed448PublicJwk _ _ -> Just Sig
     RsaPublicJwk  _ _ u _ -> u
     RsaPrivateJwk _ _ u _ -> u
     EcPublicJwk   _ _ u _ _ -> u
     EcPrivateJwk  _ _ u _ _ -> u
     SymmetricJwk  _ _ u _ -> u
+    UnsupportedJwk _ -> Nothing
 
 jwkAlg :: Jwk -> Maybe Alg
 jwkAlg key = case key of
-    Ed25519PrivateJwk _ _ _ -> Just (Signed EdDSA)
+    Ed25519PrivateJwk {} -> Just (Signed EdDSA)
     Ed25519PublicJwk _ _ -> Just (Signed EdDSA)
-    Ed448PrivateJwk _ _ _ -> Just (Signed EdDSA)
+    Ed448PrivateJwk {} -> Just (Signed EdDSA)
     Ed448PublicJwk _ _ -> Just (Signed EdDSA)
     RsaPublicJwk  _ _ _ a -> a
     RsaPrivateJwk _ _ _ a -> a
     EcPublicJwk   _ _ _ a _ -> a
     EcPrivateJwk  _ _ _ a _ -> a
     SymmetricJwk  _ _ _ a -> a
+    UnsupportedJwk _ -> Nothing
 
 
 newtype JwkBytes = JwkBytes {bytes :: ByteString} deriving (Show)
@@ -288,20 +292,33 @@
     toJSON (JwkBytes b) = String . TE.decodeUtf8 $ B64.encode b
 
 instance FromJSON Jwk where
-    parseJSON o@(Object _) = do
-        jwkData <- parseJSON o :: Parser JwkData
-        case createJwk jwkData of
-            Left  err -> fail err
-            Right jwk -> return jwk
+    parseJSON (Object k) = parseJwk k
     parseJSON _            = fail "Jwk must be a JSON object"
 
+parseJwk :: Object -> Parser Jwk
+parseJwk k =
+    case (checkAlg, checkKty) of
+        (Success _, Success _) -> do
+            jwkData <- parseJSON (Object k) :: Parser JwkData
+            case createJwk jwkData of
+                Left  err -> fail err
+                Right jwk -> return jwk
+        _ -> pure (UnsupportedJwk k)
+  where
+    algValue = fromMaybe Null (H.lookup "alg" k)
+    -- kty is required so if it's missing here we do nothing and allow decoding to fail
+    -- later
+    ktyValue = fromMaybe Null (H.lookup "kty" k)
+    checkAlg = fromJSON algValue :: Result (Maybe Alg)
+    checkKty = fromJSON ktyValue :: Result (Maybe KeyType)
+
 instance ToJSON Jwk where
-    toJSON jwk = toJSON $ case jwk of
+    toJSON jwk = case jwk of
         RsaPublicJwk pubKey mId mUse mAlg ->
-          createPubData pubKey mId mUse mAlg
+          toJSON $ createPubData pubKey mId mUse mAlg
         RsaPrivateJwk privKey mId mUse mAlg ->
             let pubData = createPubData (RSA.private_pub privKey) mId mUse mAlg
-            in  pubData
+            in  toJSON $ pubData
                 { d  = Just . JwkBytes . i2osp $ RSA.private_d privKey
                 , p  = i2b $ RSA.private_p    privKey
                 , q  = i2b $ RSA.private_q    privKey
@@ -310,7 +327,7 @@
                 , qi = i2b $ RSA.private_qinv privKey
                 }
 
-        Ed25519PrivateJwk kPr kPub kid_ -> defJwk
+        Ed25519PrivateJwk kPr kPub kid_ -> toJSON $ defJwk
             { kty = Okp
             , crv = Just "Ed25519"
             , d = Just (JwkBytes (BA.convert kPr))
@@ -318,30 +335,30 @@
             , kid = kid_
             }
 
-        Ed25519PublicJwk kPub kid_ -> defJwk
+        Ed25519PublicJwk kPub kid_ -> toJSON $ defJwk
             { kty = Okp
             , crv = Just "Ed25519"
             , x = Just (JwkBytes (BA.convert kPub))
             , kid = kid_
             }
 
-        Ed448PrivateJwk kPr kPub kid_ -> defJwk
+        Ed448PrivateJwk kPr kPub kid_ -> toJSON $ defJwk
             { kty = Okp
-            , crv = Just "Ed25519"
+            , crv = Just "Ed448"
             , d = Just (JwkBytes (BA.convert kPr))
             , x = Just (JwkBytes (BA.convert kPub))
             , kid = kid_
             }
 
-        Ed448PublicJwk kPub kid_ -> defJwk
+        Ed448PublicJwk kPub kid_ -> toJSON $ defJwk
             { kty = Okp
-            , crv = Just "Ed25519"
+            , crv = Just "Ed448"
             , x = Just (JwkBytes (BA.convert kPub))
             , kid = kid_
             }
 
 
-        SymmetricJwk bs mId mUse mAlg -> defJwk
+        SymmetricJwk bs mId mUse mAlg -> toJSON $ defJwk
             { kty = Oct
             , k   = Just $ JwkBytes bs
             , kid = mId
@@ -349,7 +366,7 @@
             , alg = mAlg
             }
 
-        EcPublicJwk pubKey mId mUse mAlg c -> defJwk
+        EcPublicJwk pubKey mId mUse mAlg c -> toJSON $ defJwk
             { kty = Ec
             , x   = fst (ecPoint pubKey)
             , y   = snd (ecPoint pubKey)
@@ -359,7 +376,7 @@
             , crv = Just (ecCurveName c)
             }
 
-        EcPrivateJwk kp mId mUse mAlg c -> defJwk
+        EcPrivateJwk kp mId mUse mAlg c -> toJSON $ defJwk
             { kty = Ec
             , x   = fst (ecPoint (ECDSA.toPublicKey kp))
             , y   = snd (ecPoint (ECDSA.toPublicKey kp))
@@ -369,6 +386,8 @@
             , alg = mAlg
             , crv = Just (ecCurveName c)
             }
+
+        UnsupportedJwk k -> Object k
       where
         i2b 0 = Nothing
         i2b i = Just . JwkBytes . i2osp $ i
@@ -503,7 +522,7 @@
     rsaPub nb eb  = let m  = os2ip $ bytes nb
                         ex = os2ip $ bytes eb
                     in RSA.PublicKey (rsaSize m 1) m ex
-    rsaSize m i   = if (2 ^ (i * 8)) > m then i else rsaSize m (i+1)
+    rsaSize m i   = if 2 ^ (i * 8) > m then i else rsaSize m (i+1)
     ecPoint       = do
         xb <- note "x is required for an EC key" x
         yb <- note "y is required for an EC key" y
diff --git a/Jose/Jws.hs b/Jose/Jws.hs
--- a/Jose/Jws.hs
+++ b/Jose/Jws.hs
@@ -28,7 +28,6 @@
     )
 where
 
-import Control.Applicative
 import qualified Crypto.PubKey.ECC.ECDSA as ECDSA
 import qualified Crypto.PubKey.Ed25519 as Ed25519
 import qualified Crypto.PubKey.Ed448 as Ed448
diff --git a/Jose/Jwt.hs b/Jose/Jwt.hs
--- a/Jose/Jwt.hs
+++ b/Jose/Jwt.hs
@@ -118,6 +118,7 @@
         EcPublicJwk   kPub _ _ _ _ -> Jws.ecDecode kPub jwt
         EcPrivateJwk  kPr  _ _ _ _ -> Jws.ecDecode (ECDSA.toPublicKey kPr) jwt
         SymmetricJwk  kb   _ _ _ -> Jws.hmacDecode kb jwt
+        UnsupportedJwk _ -> Left (KeyError "Unsupported JWKs cannot be used")
 
     decodeWithJwe :: MonadRandom m => Jwk -> ExceptT JwtError m (Maybe JwtContent)
     decodeWithJwe k = fmap (either (const Nothing) Just) (lift (Jwe.jwkDecode k jwt))
diff --git a/Jose/Types.hs b/Jose/Types.hs
--- a/Jose/Types.hs
+++ b/Jose/Types.hs
@@ -22,9 +22,7 @@
     )
 where
 
-import Control.Applicative
 import Data.Aeson
-import Data.Aeson.Types
 import Data.Char (toUpper, toLower)
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Lazy as BL
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.1
+Version:            0.9.2
 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
@@ -4,13 +4,11 @@
 
 module Tests.JweSpec where
 
-import Control.Applicative
-import Data.Aeson (decodeStrict', ToJSON)
+import Data.Aeson (decodeStrict')
 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)
@@ -68,7 +66,7 @@
       it "decodes the JWT using the JWK" $ do
         let Just k1 = decodeStrict' a1jwk
             Just k2 = decodeStrict' a2jwk
-        withBlinder (decode [k2, k1] (Just $ JweEncoding RSA_OAEP A256GCM) a1) @?= (Right $ Jwe (a1Header, a1Payload))
+        withBlinder (decode [k2, k1] (Just $ JweEncoding RSA_OAEP A256GCM) a1) @?= Right (Jwe (a1Header, a1Payload))
 
       it "a truncated CEK returns BadCrypto" $ do
         let [hdr, _, iv, payload, tag] = BC.split '.' a1
@@ -136,7 +134,7 @@
             (Jwe.jwkEncode A128KW A128CBC_HS256 jwk (Claims a3Payload)) @?= (Right (Jwt a3), RNG "")
 
       it "decodes the JWT using the JWK" $
-        withBlinder (decode [jwk] Nothing a3) @?= (Right $ Jwe (a3Header, a3Payload))
+        withBlinder (decode [jwk] Nothing a3) @?= Right (Jwe (a3Header, a3Payload))
 
     context "when used with quickcheck" $ do
       it "padded msg is always a multiple of 16" $ property $
@@ -297,7 +295,7 @@
     return $ JWEAlgs a e
 
 instance Arbitrary RNG where
-  arbitrary = (RNG . B.pack) <$> vector 600
+  arbitrary = RNG . B.pack <$> vector 600
 
 
 --------------------------------------------------------------------------------
diff --git a/tests/Tests/JwkSpec.hs b/tests/Tests/JwkSpec.hs
--- a/tests/Tests/JwkSpec.hs
+++ b/tests/Tests/JwkSpec.hs
@@ -18,7 +18,6 @@
 import Jose.Jwk
 import Jose.Jwa
 
--- TODO: Support for  {"kty": "oct", "alg": "A128KW", "k":"GawgguFyGrWKav7AX4VKUg"}
 spec :: Spec
 spec = do
     jwkFile <- runIO (B.readFile "tests/jwks.json")
@@ -45,7 +44,7 @@
                 Ed25519PrivateJwk _ _ key9Id = kss !! 9
                 Ed25519PublicJwk _ key10Id = kss !! 10
                 Success utcKeyId = fromJSON (String "2015-05-16T18:00:14.259Z")
-            length kss @?= 11
+            length kss @?= 14
             a0      @?= Nothing
             key0Id  @?= Just (KeyId "a0")
             key1Id  @?= Just (KeyId "a1")
diff --git a/tests/jwks.json b/tests/jwks.json
--- a/tests/jwks.json
+++ b/tests/jwks.json
@@ -10,5 +10,8 @@
     , {"kty":"RSA", "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e":"AQAB", "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q", "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs", "q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk", "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0", "dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk", "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU", "alg":"RS256", "kid":"2015-05-16T18:00:14.259Z"}
       , {"kty":"OKP","crv":"Ed25519", "d":"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A", "x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", "kid": "rfc8037SecretKey"}
       , {"kty":"OKP","crv":"Ed25519", "x":"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", "kid": "rfc8037PublicKey"}
+      , {"kty": "oct", "alg": "A128KW", "k":"GawgguFyGrWKav7AX4VKUg"}
+      , {"kty":"EC","use":"enc","crv":"P-256","kid":"jwe-encryption-key-from-pr-31","key_ops":["encrypt"],"x":"G8CZn6Zo7UqKLhpDFOh9njuDwBRn2xawrvf65c_t1UM","y":"L3tlkG4tQhNitkJp-5XxvqnbgBGjJFpFr-WEyIUbEvA","alg":"ECDH-ES" }
+      , {"kty": "hypothetical-new-kty", "alg": "A256KW", "k":"GawgguFyGrWKav7AX4VKUg"}
     ]
 }
