class JWSTest(TestCase): def setUp(self): self.inst = JWS() self.key = jwk_from_dict( json.loads(load_testdata('rsa_privkey.json', 'r'))) self.pubkey = jwk_from_dict( json.loads(load_testdata('rsa_pubkey.json', 'r'))) self.message = (b'{"iss":"joe",\r\n' b' "exp":1300819380,\r\n' b' "http://example.com/is_root":true}') self.compact_jws = ( 'eyJhbGciOiJSUzI1NiJ9' '.' 'eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt' 'cGxlLmNvbS9pc19yb290Ijp0cnVlfQ' '.' 'cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7' 'AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4' 'BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K' '0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv' 'hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB' 'p0igcN_IoypGlUPQGe77Rw') def test_encode(self): compact_jws = self.inst.encode(self.message, self.key, alg='RS256') self.assertEqual(compact_jws, self.compact_jws) def test_decode(self): message = self.inst.decode(self.compact_jws, self.key) self.assertEqual(message, self.message) def test_decode_pubkey(self): message = self.inst.decode(self.compact_jws, self.pubkey) self.assertEqual(message, self.message)
class JWT(Impl): def __init__(self, keys): self.keys = keys self.jws = JWS(keys) self.jwe = None def _get_impl(self, alg): if self.jws.is_supported(alg): return self.jws elif self.jwe and self.jwe.is_supported(alg): return self.jwe raise UnsupportedAlgorithm(alg) def sign(self, alg, message, kid=None): return self.jws.sign(alg, message, kid) def verify(self, jwt): encoded_header, rest = jwt.split('.', 1) headerobj = json.loads(b64_decode(encoded_header).decode('utf8')) impl = self._get_impl(headerobj['alg']) if headerobj.get('cty') == 'JWT': return self.verify(impl.decode(headerobj, rest).decode('utf8')) return impl.verify(headerobj, encoded_header, rest) def encode(self, headerobj, payload): assert isinstance(headerobj, dict) assert isinstance(payload, bytes) try: impl = self._get_impl(headerobj['alg']) except KeyError as why: raise MalformedJWT('\'alg\' is required') encoded_header = b64_encode(self._json_encode(headerobj)) return '.'.join(( encoded_header, impl.encode(headerobj, encoded_header, payload) )) def decode(self, jwt): encoded_header, rest = jwt.split('.', 1) headerobj = json.loads(b64_decode(encoded_header).decode('utf8')) impl = self._get_impl(headerobj['alg']) if not impl.verify(headerobj, encoded_header, rest): raise MalformedJWT() payload = impl.decode(headerobj, rest) if headerobj.get('cty') == 'JWT': return self.decode(payload.decode('utf8')) return payload
class JWToken(object): def __init__(self, crypth='rsa'): # Setup _is_rsa = crypth != 'oct' # Private key load _key_load = not _is_rsa and load_file_keys( JWTSetting.JWT_OCT_KEY, 'r') or load_file_keys( JWTSetting.JWT_RSA_PRIVATE_KEY) # Json Web Service self.jws = JWS() # Algorithm self.alg = not _is_rsa and 'HS256' or 'RS256' # Private key processing self.jwk = not _is_rsa and jwk_from(_key_load) or jwk_from( _key_load, 'pem') def jwt_target(self): return self.jwk def jwt_get_payload(self, user): return json.dumps({ 'user': user.pk, 'email': user.email, 'exp': time.mktime( (datetime.utcnow() + JWTSetting.JWT_EXPIRE).timetuple()) }).encode() def jwt_verify(self, jwt) -> bool: return bool(self.jwt_decode(jwt)) def jwt_encode(self, payload) -> (str, bool): try: return self.jws.encode(message=payload, key=self.jwk, alg=self.alg) except JWSEncodeError: return False def jwt_decode(self, jwt: str) -> (str, bool): try: return json.loads( self.jws.decode(message=jwt, key=self.jwk).decode('utf-8')) except JWSDecodeError: return False def get_authorization_header(self, request): """ Return request's 'Authorization:' header, as a bytestring. From: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/authentication.py """ auth = request.META.get('HTTP_AUTHORIZATION', b'') if isinstance(auth, str): # Work around django test client oddness auth = auth.encode('iso-8859-1') return auth
def setUp(self): # local _jwt = JWToken('rsa') self.jws = JWS() self.jwk = _jwt.jwt_target() # Default message self.message = b'{"user": 1, "email": "*****@*****.**","exp": "1486947255.0"}' # Compressed self.compact = 'eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjogMSwgImVtYWlsIjogImdtanVuMjAwMEBnbWFpbC5jb20iLCJleHAiOiAiMTQ4Njk0NzI1NS4wIn0.L57CzBbMf1aL413EfmVq_mDNCy6Fyh6zRG3wyh_EZP3kJAY_dnuYyD3siEJT2ebhGVmkB0v6YRT6jshi2gCuiAd4xahwsk9MrNsx0_atPJmzRiJr0sVf19iaaVBuVD8ltDDr8Lhh9ccBLgTmzEsHTzQwA-Krb32yApT5a16Mt_Q'
def __init__(self, crypth='rsa'): # Setup _is_rsa = crypth != 'oct' # Private key load _key_load = not _is_rsa and load_file_keys( JWTSetting.JWT_OCT_KEY, 'r') or load_file_keys( JWTSetting.JWT_RSA_PRIVATE_KEY) # Json Web Service self.jws = JWS() # Algorithm self.alg = not _is_rsa and 'HS256' or 'RS256' # Private key processing self.jwk = not _is_rsa and jwk_from(_key_load) or jwk_from( _key_load, 'pem')
class TestJWSRSA(TestCase): def setUp(self): # local _jwt = JWToken('rsa') self.jws = JWS() self.jwk = _jwt.jwt_target() # Default message self.message = b'{"user": 1, "email": "*****@*****.**","exp": "1486947255.0"}' # Compressed self.compact = 'eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjogMSwgImVtYWlsIjogImdtanVuMjAwMEBnbWFpbC5jb20iLCJleHAiOiAiMTQ4Njk0NzI1NS4wIn0.L57CzBbMf1aL413EfmVq_mDNCy6Fyh6zRG3wyh_EZP3kJAY_dnuYyD3siEJT2ebhGVmkB0v6YRT6jshi2gCuiAd4xahwsk9MrNsx0_atPJmzRiJr0sVf19iaaVBuVD8ltDDr8Lhh9ccBLgTmzEsHTzQwA-Krb32yApT5a16Mt_Q' def test_is_abstract_jwk(self): assert isinstance(self.jwk, AbstractJWKBase) def test_is_rsa_instance(self): assert isinstance(self.jwk, RSAJWK) assert isinstance(self.jwk.keyobj, RSAPrivateKey) def test_decode(self): _pub = jwk_from( load_file_keys( 'publickey.pem' ), 'pem' ) _message = self.jws.decode( self.compact, _pub ) self.assertEqual( _message, self.message ) def test_encode_rsa(self): _encode = self.jws.encode( message=self.message, key=self.jwk, alg='RS256' ) self.assertEqual( _encode, self.compact )
def setUp(self): self.inst = JWS() self.key = jwk_from_dict( json.loads(load_testdata('rsa_privkey.json', 'r'))) self.pubkey = jwk_from_dict( json.loads(load_testdata('rsa_pubkey.json', 'r'))) self.message = ( b'{"iss":"joe",\r\n' b' "exp":1300819380,\r\n' b' "http://example.com/is_root":true}' ) self.compact_jws = ( 'eyJhbGciOiJSUzI1NiJ9' '.' 'eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt' 'cGxlLmNvbS9pc19yb290Ijp0cnVlfQ' '.' 'cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7' 'AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4' 'BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K' '0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqv' 'hJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrB' 'p0igcN_IoypGlUPQGe77Rw' )
def __init__(self, keys): self.keys = keys self.jws = JWS(keys) self.jwe = None