JOSE [1] is a framework intended to provide a method to securely transfer
claims (such as authorization information) between parties. The JOSE
framework provides a collection of specifications to serve this purpose. A
JSON Web Token (JWT) [2] contains claims that can be used to
allow a system to apply access control to resources it owns. One potential
use case of the JWT is as the means of authentication and authorization
for a system that exposes resources through an OAuth 2.0 model [5].

Claims are a set of key/value pairs that provide a target system with
sufficient information about the given client to apply the appropriate level of
access control to resources under its ownership. Claim names are split into
three classes: Registered (IANA), Public and Private. Further details about
claims can be found in section 4 of the JWT specification.

JWTs can be represented as either JSON Web Signature (JWS) [3] or a
JSON Web Encryption (JWE) [4] objects. Claims within a JWS can be read
as they are simply base64-encoded (but carry with them a signature for
authentication). Claims in a JWE on the other hand, are encrypted and as such,
are entirely opaque to clients using them as their means of authentication
and authorization.

A JSON Web Key (JWK) [6] is a JSON data structure that represents a
cryptographic key. Using a JWK rather than one or more parameters allows for a
generalized key as input that can be applied to a number of different
algorithms that may expect a different number of inputs. All JWE and JWS
operations expect a JWK rather than inflexible function parameters.

Currently, the only key/value pair that’s required throughout the JWE and JWS
flows is ‘k’, indicating the key, or password.

Note

The password must match algorithm requirements (i.e. a key used with
an RSA algorithm must be at least 2048 bytes and be a valid private
or public key, depending on the cryptographic operation).
Other fields may be required in future releases.

importjoseclaims={'iss':'http://www.example.com','exp':int(time())+3600,'sub':42,}jwk={'k':'password'}jws=jose.sign(claims,jwk,alg='HS256')# JWS(header='eyJhbGciOiAiSFMyNTYifQ',# payload='eyJpc3MiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbSIsICJzdWIiOiA0MiwgImV4cCI6IDEzOTU2NzQ0Mjd9',# signature='WYApAiwiKd-eDClA1fg7XFrnfHzUTgrmdRQY4M19Vr8')# issue the compact serialized version to the clients. this is what will be# transported along with requests to target systems.jwt=jose.serialize_compact(jws)# 'eyJhbGciOiAiSFMyNTYifQ.eyJpc3MiOiAiaHR0cDovL3d3dy5leGFtcGxlLmNvbSIsICJzdWIiOiA0MiwgImV4cCI6IDEzOTU2NzQ0Mjd9.WYApAiwiKd-eDClA1fg7XFrnfHzUTgrmdRQY4M19Vr8'jose.verify(jose.deserialize_compact(jwt),jwk,'HS256')# JWT(header={u'alg': u'HS256'}, claims={u'iss': u'http://www.example.com', u'sub': 42, u'exp': 1395674427})

importjosefromtimeimporttimefromCrypto.PublicKeyimportRSA# key for demonstration purposeskey=RSA.generate(2048)claims={'iss':'http://www.example.com','exp':int(time())+3600,'sub':42,}# encrypt claims using the public keypub_jwk={'k':key.publickey().exportKey('PEM')}jwe=jose.encrypt(claims,pub_jwk)# JWE(header='eyJhbGciOiAiUlNBLU9BRVAiLCAiZW5jIjogIkExMjhDQkMtSFMyNTYifQ',# cek='SsLgP2bNKYDYGzHvLYY7rsVEBHSms6_jW-WfglHqD9giJhWwrOwqLZOaoOycsf_EBJCkHq9-vbxRb7WiNdy_C9J0_RnRRBGII6z_G4bVb18bkbJMeZMV6vpUut_iuRWoct_weg_VZ3iR2xMbl-yE8Hnc63pAGJcIwngfZ3sMX8rBeni_koxCc88LhioP8zRQxNkoNpvw-kTCz0xv6SU_zL8p79_-_2zilVyMt76Pc7WV46iI3EWIvP6SG04sguaTzrDXCLp6ykLGaXB7NRFJ5PJ9Lmh5yinAJzCdWQ-4XKKkNPorSiVmRiRSQ4z0S2eo2LtvqJhXCrghKpBNgbtnJQ',# iv='Awelp3ryBVpdFhRckQ-KKw',# ciphertext='1MyZ-3nky1EFO4UgTB-9C2EHpYh1Z-ij0RbiuuMez70nIH7uqL9hlhskutO0oPjqdpmNc9glSmO9pheMH2DVag',# tag='Xccck85XZMvG-fAJ6oDnAw')# issue the compact serialized version to the clients. this is what will be# transported along with requests to target systems.jwt=jose.serialize_compact(jwe)# 'eyJhbGciOiAiUlNBLU9BRVAiLCAiZW5jIjogIkExMjhDQkMtSFMyNTYifQ.SsLgP2bNKYDYGzHvLYY7rsVEBHSms6_jW-WfglHqD9giJhWwrOwqLZOaoOycsf_EBJCkHq9-vbxRb7WiNdy_C9J0_RnRRBGII6z_G4bVb18bkbJMeZMV6vpUut_iuRWoct_weg_VZ3iR2xMbl-yE8Hnc63pAGJcIwngfZ3sMX8rBeni_koxCc88LhioP8zRQxNkoNpvw-kTCz0xv6SU_zL8p79_-_2zilVyMt76Pc7WV46iI3EWIvP6SG04sguaTzrDXCLp6ykLGaXB7NRFJ5PJ9Lmh5yinAJzCdWQ-4XKKkNPorSiVmRiRSQ4z0S2eo2LtvqJhXCrghKpBNgbtnJQ.Awelp3ryBVpdFhRckQ-KKw.1MyZ-3nky1EFO4UgTB-9C2EHpYh1Z-ij0RbiuuMez70nIH7uqL9hlhskutO0oPjqdpmNc9glSmO9pheMH2DVag.Xccck85XZMvG-fAJ6oDnAw'# decrypt on the other end using the private keypriv_jwk={'k':key.exportKey('PEM')}jwt=jose.decrypt(jose.deserialize_compact(jwt),priv_jwk)# JWT(header={u'alg': u'RSA-OAEP', u'enc': u'A128CBC-HS256'},# claims={u'iss': u'http://www.example.com', u'sub': 42, u'exp': 1395606273})

There are two different encryption algorithms employed to fully encrypt a JWE:
Encryption of the Content Encryption Key (CEK) and encryption of the JWT
claims. The encryption algorithm used to encrypt the CEK is set through the
alg parameter of encrypt() and the claims encryption is defined
by the enc parameter.