def test_pjwt_with_jwe_jwk(): keys = KEYS() keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id")) jwe = JWE(alg="RSA-OAEP", enc="A256CBC-HS512") pj = PopJWT("https://server.example.com", "https://client.example.org", sub='12345678', jwe=jwe, keys=keys) jwk = { "kty": "oct", "alg": "HS256", "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE" } pjwt = pj.pack_jwe(jwk=jwk, kid='some-key-id') s = pjwt.to_json() de_pjwt = PJWT().from_json(s) assert _eq(de_pjwt.keys(), ['iss', 'aud', 'exp', 'cnf', 'sub', 'iat']) assert list(de_pjwt['cnf'].keys()) == ['jwe'] _jwe = de_pjwt['cnf']['jwe'] msg = jwe.decrypt(_jwe, keys.keys()) assert msg assert json.loads(msg.decode('utf8')) == jwk
def test_sign_2(): keyset = { "keys": [{ "alg": "RS512", "kty": "RSA", "d": "ckLyXxkbjC4szg8q8G0ERBZV" "-9CszeOxpRtx1KM9BLl0Do3li_Km2vvFvfXJ7MxQpiZ18pBoCcyYQEU262ym8wI22JWMPrZe24HCNxLxqzr_JEuBhpKFxQF6EFTSvJEJD1FkoTuCTvN0zD7YHGaJQG6JzVEuFUY3ewxjH0FYNa_ppTnPP3LC-T9u_GX9Yqyuw1KOYoHSzhWSWQOeAgs4dH9-iAxN1wdZ6eH1jFWAs43svk_rhwdgyJMlihFtV9MAInBlfi_Zu8wRVhVl5urkJrLf0tGFnMbnzb6dYSlUXxEYClpY12W7kXW9aePDqkCwI4oZyxmOmgq4hunKGR1dAQ", "e": "AQAB", "use": "sig", "kid": "af22448d-4c7b-464d-b63a-f5bd90f6d7d1", "n": "o9g8DpUwBW6B1qmcm-TfEh4rNX7n1t38jdo4Gkl_cI3q" "--7n0Blg0kN88LHZvyZjUB2NhBdFYNxMP8ucy0dOXvWGWzaPmGnq3DM__lN8P4WjD1cCTAVEYKawNBAmGKqrFj1SgpPNsSqiqK-ALM1w6mZ-QGimjOgwCyJy3l9lzZh5D8tKnS2t1pZgE0X5P7lZQWHYpHPqp4jKhETzrCpPGfv0Rl6nmmjp7NlRYBkWKf_HEKE333J6M039m2FbKgxrBg3zmYYpmHuMzVgxxb8LSiv5aqyeyJjxM-YDUAgNQBfKNhONqXyu9DqtSprNkw6sqmuxK0QUVrNYl3b03PgS5Q" }] } keys = KEYS() keys.load_dict(keyset) jws = JWS("payload", alg="RS512") jws.sign_compact(keys=keys)
def jwks(self): # TODO: some cache with respect of self.issuer_config # now keys are being reloaded every time # (doesn't matter for Zappa until keys are cached to Redis) keys = KEYS() keys.load_from_url(self.oidc_config['jwks_uri']) return keys
def __missing__(self, kid): """ Loads the public key for this handler from the OIDC service. Raises PublicKeyLoadException on failure. """ keys_url = self._login_service._oidc_config()["jwks_uri"] # Load the keys. try: keys = KEYS() keys.load_from_url( keys_url, verify=not self._login_service.config.get("DEBUGGING", False)) except Exception as ex: logger.exception("Exception loading public key") raise PublicKeyLoadException(str(ex)) # Find the matching key. keys_found = keys.by_kid(kid) if len(keys_found) == 0: raise PublicKeyLoadException("Public key %s not found" % kid) rsa_keys = [key for key in keys_found if key.kty == "RSA"] if len(rsa_keys) == 0: raise PublicKeyLoadException( "No RSA form of public key %s not found" % kid) matching_key = rsa_keys[0] matching_key.deserialize() # Reload the key so that we can give a key *instance* to PyJWT to work around its weird parsing # issues. final_key = load_der_public_key(matching_key.key.exportKey("DER"), backend=default_backend()) self[kid] = final_key return final_key
class JWT_Verification(): def __init__(self): self.SIGKEYS = KEYS() keys_json = self.getKeys_JWT() self.SIGKEYS.load_dict(keys_json) def verify_signature_JWT(self, jwt): symkeys = [k for k in self.SIGKEYS if k.alg == "RS256"] _rj = JWS() info = _rj.verify_compact(jwt, symkeys) decoded_json = self.decode_JWT(jwt) if info == decoded_json: return True else: return False def decode_JWT(self, jwt): payload = str(jwt).split(".")[1] paddedPayload = payload + '=' * (4 - len(payload) % 4) decoded = base64.b64decode(paddedPayload) decoded_json = json.loads(decoded) return decoded_json
class JWT_Verification(): def __init__(self): self.SIGKEYS = KEYS() keys_json = self.getKeys_JWT() self.SIGKEYS.load_dict(keys_json) def verify_signature_JWT(self, jwt): symkeys = [k for k in self.SIGKEYS if k.alg == "RS256"] _rj = JWS() info = _rj.verify_compact(jwt, symkeys) decoded_json = self.decode_JWT(jwt) if info == decoded_json: return True else: return False def getKeys_JWT(self): g_config = load_config("./config/config.json") headers = { 'content-type': "application/json", "cache-control": "no-cache" } res = requests.get(g_config["auth_server_url"]+"/oxauth/restv1/jwks", headers=headers, verify=False) json_dict = json.loads(res.text) return json_dict def decode_JWT(self, jwt): payload = str(jwt).split(".")[1] paddedPayload = payload + '=' * (4 - len(payload) % 4) decoded = base64.b64decode(paddedPayload) decoded_json = json.loads(decoded) return decoded_json
def test_loads_1(): jwk = { "keys": [ { "kty": "RSA", "use": "foo", "e": "AQAB", "n": "wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8", "kid": "1", }, { "kty": "RSA", "use": "bar", "e": "AQAB", "n": "wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8", "kid": "2", }, ] } keys = KEYS() keys.load_dict(jwk) print(keys) assert len(keys) == 2 assert _eq(keys.kids(), ["1", "2"])
def test_pjwt_unpack_jwe(): keys = KEYS() keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id")) pj = PopJWT("https://server.example.com", "https://client.example.org", sub="12345678") jwk = { "kty": "oct", "alg": "HS256", "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE", } jwe = JWE(json.dumps(jwk), alg="RSA-OAEP", enc="A256CBC-HS512") _jwe = jwe.encrypt(keys=keys.keys(), kid="some-key-id") pjwt = pj.pack_jwe(jwe=_jwe) s = pjwt.to_json() _jwt = PopJWT(jwe=jwe, keys=keys).unpack(s) assert _eq(_jwt.keys(), ["iss", "aud", "exp", "cnf", "sub", "iat"]) assert _eq(_jwt["cnf"].keys(), ["jwk", "jwe"]) assert _jwt["cnf"]["jwk"] == jwk
def test_pjwt_with_jwe_jwk(): keys = KEYS() keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id")) jwe = JWE(alg="RSA-OAEP", enc="A256CBC-HS512") pj = PopJWT( "https://server.example.com", "https://client.example.org", sub="12345678", jwe=jwe, keys=keys, ) jwk = { "kty": "oct", "alg": "HS256", "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE", } pjwt = pj.pack_jwe(jwk=jwk, kid="some-key-id") s = pjwt.to_json() de_pjwt = PJWT().from_json(s) assert _eq(de_pjwt.keys(), ["iss", "aud", "exp", "cnf", "sub", "iat"]) assert list(de_pjwt["cnf"].keys()) == ["jwe"] _jwe = de_pjwt["cnf"]["jwe"] msg = jwe.decrypt(_jwe, keys.keys()) assert msg assert json.loads(msg.decode("utf8")) == jwk
def test_pjwt_unpack_jwe(): keys = KEYS() keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id")) pj = PopJWT("https://server.example.com", "https://client.example.org", sub='12345678') jwk = { "kty": "oct", "alg": "HS256", "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE" } jwe = JWE(json.dumps(jwk), alg="RSA-OAEP", enc="A256CBC-HS512") _jwe = jwe.encrypt(keys=keys.keys(), kid="some-key-id") pjwt = pj.pack_jwe(jwe=_jwe) s = pjwt.to_json() _jwt = PopJWT(jwe=jwe, keys=keys).unpack(s) assert _eq(_jwt.keys(), ['iss', 'aud', 'exp', 'cnf', 'sub', 'iat']) assert _eq(_jwt['cnf'].keys(), ['jwk', 'jwe']) assert _jwt['cnf']['jwk'] == jwk
def make_request_object(request_args, jwk): keys = KEYS() jws = JWS(request_args) if jwk: keys.load_jwks(json.dumps(dict(keys=[jwk]))) return jws.sign_compact(keys)
def get_jwks_keys(self): keys = KEYS() keys.load_from_url(self.jwks_uri()) # Add client secret as oct key so it can be used for HMAC signatures client_id, client_secret = self.get_key_and_secret() keys.add({'key': client_secret, 'kty': 'oct'}) return keys
def signing_keys(self): if self.signing_alg == self.RS256: # TODO perform caching, OBVIOUS key = KEYS() key.load_from_url(self.jwks_uri) rsa_key = key.as_dict()['RSA'] return rsa_key return [SYMKey(key=str(self.client_secret))]
def test_dump_jwk(): keylist0 = KEYS() keylist0.wrap_add(pem_cert2rsa(CERT)) jwk = keylist0.dump_jwks() print(jwk) _wk = json.loads(jwk) assert list(_wk.keys()) == ["keys"] assert len(_wk["keys"]) == 1 assert _eq(list(_wk["keys"][0].keys()), ["kty", "e", "n"])
def _get_keys(self): """ Get public key from discovery. """ request = self.factory.get(reverse('oidc_provider:jwks')) response = JwksView.as_view()(request) jwks_dic = json.loads(response.content.decode('utf-8')) SIGKEYS = KEYS() SIGKEYS.load_dict(jwks_dic) return SIGKEYS
def setUp(self): self.user = User.objects.create(username='******') mock_get = self.patch('requests.get') mock_get.return_value.json.return_value = {"jwks_uri": "http://example.com/jwks", "issuer": "http://example.com"} keys = KEYS() keys.add({'key': key, 'kty': 'RSA'}) self.patch('jwkest.jwk.request', return_value=Mock(status_code=200, text=keys.dump_jwks())) api_settings.OIDC_ENDPOINT = 'http://example.com' api_settings.OIDC_AUDIENCE = 'you'
def test_loads_0(): keys = KEYS() keys.load_dict(JWK) assert len(keys) == 1 key = keys["rsa"][0] assert key.kid == 'abc' assert key.kty == 'RSA' _ckey = pem_cert2rsa(CERT) print(key) assert key.n == _ckey.n assert key.e == _ckey.e
def setUp(self): self.user = User.objects.create(username='******') self.responder = FakeRequests() self.responder.set_response("http://example.com/.well-known/openid-configuration", {"jwks_uri": "http://example.com/jwks", "issuer": "http://example.com", "userinfo_endpoint": "http://example.com/userinfo"}) self.mock_get = self.patch('requests.get') self.mock_get.side_effect = self.responder.get keys = KEYS() keys.add({'key': key, 'kty': 'RSA', 'kid': key.kid}) self.patch('oidc_auth.authentication.request', return_value=Mock(status_code=200, text=keys.dump_jwks()))
def get_jwks_keys(self): """ Returns the keys used to decode the ID token. Note: edX uses symmetric keys, so bypass the parent class's calls to an external server and return the key from settings. """ keys = KEYS() keys.add({ 'key': self.setting('ID_TOKEN_DECRYPTION_KEY'), 'kty': 'oct' }) return keys
def setUp(self): self.user = User.objects.create(username='******') self.responder = FakeRequests() self.responder.set_response("http://example.com/.well-known/openid-configuration", {"jwks_uri": "http://example.com/jwks", "issuer": "http://example.com", "userinfo_endpoint": "http://example.com/userinfo"}) self.mock_get = self.patch('requests.get') self.mock_get.side_effect = self.responder.get keys = KEYS() keys.add({'key': key, 'kty': 'RSA', 'kid': key.kid}) self.patch('jwkest.jwk.request', return_value=Mock(status_code=200, text=keys.dump_jwks()))
def get_jwks_keys(self): """ Returns the keys used by the IdP. Merges client secret into JWK set from server Response is cached for 24 hours. """ keys = KEYS() keys.load_from_url(self.JWKS_URI) # Add client secret as oct key so it can be used for HMAC signatures _client_id, client_secret = self.get_key_and_secret() keys.add({'key': client_secret, 'kty': 'oct'}) return keys
def test_sign_2(): keyset = {"keys": [ {"alg": "RS512", "kty": "RSA", "d": "ckLyXxkbjC4szg8q8G0ERBZV-9CszeOxpRtx1KM9BLl0Do3li_Km2vvFvfXJ7MxQpiZ18pBoCcyYQEU262ym8wI22JWMPrZe24HCNxLxqzr_JEuBhpKFxQF6EFTSvJEJD1FkoTuCTvN0zD7YHGaJQG6JzVEuFUY3ewxjH0FYNa_ppTnPP3LC-T9u_GX9Yqyuw1KOYoHSzhWSWQOeAgs4dH9-iAxN1wdZ6eH1jFWAs43svk_rhwdgyJMlihFtV9MAInBlfi_Zu8wRVhVl5urkJrLf0tGFnMbnzb6dYSlUXxEYClpY12W7kXW9aePDqkCwI4oZyxmOmgq4hunKGR1dAQ", "e": "AQAB", "use": "sig", "kid": "af22448d-4c7b-464d-b63a-f5bd90f6d7d1", "n": "o9g8DpUwBW6B1qmcm-TfEh4rNX7n1t38jdo4Gkl_cI3q--7n0Blg0kN88LHZvyZjUB2NhBdFYNxMP8ucy0dOXvWGWzaPmGnq3DM__lN8P4WjD1cCTAVEYKawNBAmGKqrFj1SgpPNsSqiqK-ALM1w6mZ-QGimjOgwCyJy3l9lzZh5D8tKnS2t1pZgE0X5P7lZQWHYpHPqp4jKhETzrCpPGfv0Rl6nmmjp7NlRYBkWKf_HEKE333J6M039m2FbKgxrBg3zmYYpmHuMzVgxxb8LSiv5aqyeyJjxM-YDUAgNQBfKNhONqXyu9DqtSprNkw6sqmuxK0QUVrNYl3b03PgS5Q" }]} keys = KEYS() keys.load_dict(keyset) jws = JWS("payload", alg="RS512") jws.sign_compact(keys=keys)
def _get_keys(self): if "jwk" in self: return [self["jwk"]] elif "jku" in self: keys = KEYS() keys.load_from_url(self["jku"]) return keys.as_dict() elif "x5u" in self: try: return {"rsa": [load_x509_cert(self["x5u"], {})]} except Exception: # ca_chain = load_x509_cert_chain(self["x5u"]) pass return {}
def encode(self, payload): """Encode the provided payload.""" keys = KEYS() if self.asymmetric: keys.add(RSAKey(key=RSA.importKey(settings.JWT_PRIVATE_SIGNING_KEY))) algorithm = 'RS512' else: key = self.secret if self.secret else self.jwt_auth['JWT_SECRET_KEY'] keys.add({'key': key, 'kty': 'oct'}) algorithm = self.jwt_auth['JWT_ALGORITHM'] data = json.dumps(payload) jws = JWS(data, alg=algorithm) return jws.sign_compact(keys=keys)
def test_load_jwk(): keylist0 = KEYS() keylist0.wrap_add(pem_cert2rsa(CERT)) jwk = keylist0.dump_jwks() keylist1 = KEYS() keylist1.load_jwks(jwk) print(keylist1) assert len(keylist1) == 1 key = keylist1["rsa"][0] assert key.kty == 'RSA' assert isinstance(key.key, RsaKey)
def _get_signing_jwk_key_set(jwt_issuer): """ Returns a JWK Keyset containing all active keys that are configured for verifying signatures. """ key_set = KEYS() # asymmetric keys signing_jwk_set = settings.JWT_AUTH.get('JWT_PUBLIC_SIGNING_JWK_SET') if signing_jwk_set: key_set.load_jwks(signing_jwk_set) # symmetric key key_set.add({'key': jwt_issuer['SECRET_KEY'], 'kty': 'oct'}) return key_set
def _get_keys(self): logger.debug("_get_keys(): self._dict.keys={0}".format( self._dict.keys())) if "jwk" in self: return [self["jwk"]] elif "jku" in self: keys = KEYS() keys.load_from_url(self["jku"]) return keys.as_dict() elif "x5u" in self: try: return {"rsa": [load_x509_cert(self["x5u"], {})]} except Exception: # ca_chain = load_x509_cert_chain(self["x5u"]) pass return {}
def _decode_jwt(verify_expiration): """ Helper method to decode a JWT with the ability to verify the expiration of said token """ keys = KEYS() if should_be_asymmetric_key: keys.load_jwks(settings.JWT_AUTH['JWT_PUBLIC_SIGNING_JWK_SET']) else: keys.add({'key': secret_key, 'kty': 'oct'}) _ = JWS().verify_compact(access_token.encode('utf-8'), keys) return jwt.decode( access_token, secret_key, algorithms=[settings.JWT_AUTH['JWT_ALGORITHM']], audience=audience, issuer=issuer, verify_expiration=verify_expiration, options={'verify_signature': False}, )
def test_idtoken_sign_validation(self): """ We MUST validate the signature of the ID Token according to JWS using the algorithm specified in the alg Header Parameter of the JOSE Header. """ # Get public key from discovery. request = self.factory.get(reverse('oidc_provider:jwks')) response = JwksView.as_view()(request) jwks_dic = json.loads(response.content.decode('utf-8')) SIGKEYS = KEYS() SIGKEYS.load_dict(jwks_dic) RSAKEYS = [ k for k in SIGKEYS if k.kty == 'RSA' ] code = self._create_code() post_data = self._post_data(code=code.code) response = self._post_request(post_data) response_dic = json.loads(response.content.decode('utf-8')) id_token = JWS().verify_compact(response_dic['id_token'].encode('utf-8'), RSAKEYS)
def test_keys(): keyl = KEYS() keyl.load_dict(JWKS) assert len(keyl) == 3 print(keyl.keys()) print(keyl.dump_jwks()) assert _eq(keyl.key_types(), ['RSA', 'oct', 'EC']) assert len(keyl['rsa']) == 1 assert len(keyl['oct']) == 1 assert len(keyl['ec']) == 1
def test_load_jwk(): keylist0 = KEYS() keylist0.wrap_add(pem_cert2rsa(CERT)) jwk = keylist0.dump_jwks() keylist1 = KEYS() keylist1.load_jwks(jwk) print(keylist1) assert len(keylist1) == 1 key = keylist1["rsa"][0] assert key.kty == 'RSA' assert isinstance(key.key, _RSAobj)
def test_pjwt_unpack_jwe(): keys = KEYS() keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id")) pj = PopJWT("https://server.example.com", "https://client.example.org", sub='12345678') jwk = {"kty": "oct", "alg": "HS256", "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE"} jwe = JWE(json.dumps(jwk), alg="RSA-OAEP", enc="A256CBC-HS512") _jwe = jwe.encrypt(keys=keys.keys(), kid="some-key-id") pjwt = pj.pack_jwe(jwe=_jwe) s = pjwt.to_json() _jwt = PopJWT(jwe=jwe, keys=keys).unpack(s) assert _eq(_jwt.keys(), ['iss', 'aud', 'exp', 'cnf', 'sub', 'iat']) assert _eq(_jwt['cnf'].keys(), ['jwk', 'jwe']) assert _jwt['cnf']['jwk'] == jwk
def test_idtoken_sign_validation(self): """ We MUST validate the signature of the ID Token according to JWS using the algorithm specified in the alg Header Parameter of the JOSE Header. """ # Get public key from discovery. request = self.factory.get(reverse('oidc_provider:jwks')) response = JwksView.as_view()(request) jwks_dic = json.loads(response.content.decode('utf-8')) SIGKEYS = KEYS() SIGKEYS.load_dict(jwks_dic) RSAKEYS = [k for k in SIGKEYS if k.kty == 'RSA'] code = self._create_code() post_data = self._post_data(code=code.code) response = self._post_request(post_data) response_dic = json.loads(response.content.decode('utf-8')) id_token = JWS().verify_compact( response_dic['id_token'].encode('utf-8'), RSAKEYS)
def test_loads_1(): jwk = { "keys": [{ 'kty': 'RSA', 'use': 'foo', 'e': 'AQAB', "n": 'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8', 'kid': "1" }, { 'kty': 'RSA', 'use': 'bar', 'e': 'AQAB', "n": 'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8', 'kid': "2" }] } keys = KEYS() keys.load_dict(jwk) print(keys) assert len(keys) == 2 assert _eq(keys.kids(), ['1', '2'])
def test_loads_1(): jwk = { "keys": [ { 'kty': 'RSA', 'use': 'foo', 'e': 'AQAB', "n": 'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8', 'kid': "1" }, { 'kty': 'RSA', 'use': 'bar', 'e': 'AQAB', "n": 'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8', 'kid': "2" } ] } keys = KEYS() keys.load_dict(jwk) print(keys) assert len(keys) == 2 assert _eq(keys.kids(), ['1', '2'])
def test_pjwt_with_jwe_jwk(): keys = KEYS() keys.append(RSAKey(use="enc", key=rsa, kid="some-key-id")) jwe = JWE(alg="RSA-OAEP", enc="A256CBC-HS512") pj = PopJWT("https://server.example.com", "https://client.example.org", sub='12345678', jwe=jwe, keys=keys) jwk = {"kty": "oct", "alg": "HS256", "k": "ZoRSOrFzN_FzUA5XKMYoVHyzff5oRJxl-IXRtztJ6uE"} pjwt = pj.pack_jwe(jwk=jwk, kid='some-key-id') s = pjwt.to_json() de_pjwt = PJWT().from_json(s) assert _eq(de_pjwt.keys(), ['iss', 'aud', 'exp', 'cnf', 'sub', 'iat']) assert list(de_pjwt['cnf'].keys()) == ['jwe'] _jwe = de_pjwt['cnf']['jwe'] msg = jwe.decrypt(_jwe, keys.keys()) assert msg assert json.loads(msg.decode('utf8')) == jwk
def test_keys(): keyl = KEYS() keyl.load_dict(JWKS) assert len(keyl) == 3 print(keyl.keys()) print(keyl.dump_jwks()) assert _eq(keyl.key_types(), ["RSA", "oct", "EC"]) assert len(keyl["rsa"]) == 1 assert len(keyl["oct"]) == 1 assert len(keyl["ec"]) == 1
def test_keys(): keyl = KEYS() keyl.load_dict(JWKS) assert len(keyl) == 3 print(keyl.keys()) print(keyl.dump_jwks()) assert _eq(keyl.keys(), ['RSA', 'oct', 'EC']) assert len(keyl['rsa']) == 1 assert len(keyl['oct']) == 1 assert len(keyl['ec']) == 1
def _get_jwks_keys(shared_key): """ Returns JWKS keys used to decrypt id_token values. """ # The OpenID Connect Provider (OP) uses RSA keys to sign/enrypt ID tokens and generate public # keys allowing to decrypt them. These public keys are exposed through the 'jwks_uri' and should # be used to decrypt the JWS - JSON Web Signature. jwks_keys = KEYS() jwks_keys.load_from_url(oidc_rp_settings.PROVIDER_JWKS_ENDPOINT) # Adds the shared key (which can correspond to the client_secret) as an oct key so it can be # used for HMAC signatures. jwks_keys.add({'key': smart_bytes(shared_key), 'kty': 'oct'}) return jwks_keys
def _get_jwks_keys(shared_key): """ Returns JWKS keys used to decrypt id_token values. """ # The OpenID Connect Provider (OP) uses RSA keys to sign/enrypt ID tokens and generate public # keys allowing to decrypt them. These public keys are exposed through the 'jwks_uri' and should # be used to decrypt the JWS - JSON Web Signature. log_prompt = "Get jwks keys: {}" logger.debug(log_prompt.format('Start')) jwks_keys = KEYS() logger.debug(log_prompt.format('Load from provider jwks endpoint')) jwks_keys.load_from_url(settings.AUTH_OPENID_PROVIDER_JWKS_ENDPOINT) # Adds the shared key (which can correspond to the client_secret) as an oct key so it can be # used for HMAC signatures. logger.debug(log_prompt.format('Add key')) jwks_keys.add({'key': smart_bytes(shared_key), 'kty': 'oct'}) logger.debug(log_prompt.format('End')) return jwks_keys
def encode(self, payload): """Encode the provided payload.""" keys = KEYS() if self.asymmetric: keys.add( RSAKey(key=RSA.importKey(settings.JWT_PRIVATE_SIGNING_KEY))) algorithm = 'RS512' else: key = self.secret if self.secret else self.jwt_auth[ 'JWT_SECRET_KEY'] keys.add({'key': key, 'kty': 'oct'}) algorithm = self.jwt_auth['JWT_ALGORITHM'] data = json.dumps(payload) jws = JWS(data, alg=algorithm) return jws.sign_compact(keys=keys)
"k": b"YTEyZjBlMDgxMGI4YWU4Y2JjZDFiYTFlZTBjYzljNDU3YWM0ZWNiNzhmNmFlYTNkNTY0NzMzYjE", "kty": "oct", "use": "sig" }, { "kty": "EC", "kid": "7snis", "use": "sig", "x": "q0WbWhflRbxyQZKFuQvh2nZvg98ak-twRoO5uo2L7Po", "y": "GOd2jL_6wa0cfnyA0SmEhok9fkYEnAHFKLLM79BZ8_E", "crv": "P-256" } ]} SIGKEYS = KEYS() SIGKEYS.load_dict(JWKS) def test_1(): claimset = {"iss": "joe", "exp": 1300819380, "http://example.com/is_root": True} _jws = JWS(claimset, cty="JWT") _jwt = _jws.sign_compact() _jr = JWS() _msg = _jr.verify_compact(_jwt, allow_none=True) print(_jr) assert _jr.jwt.headers["alg"] == 'none' assert _msg == claimset
def test_thumbprint(): keyl = KEYS() keyl.load_dict(JWKS) for key in keyl: txt = key.thumbprint('SHA-256') assert b64e(txt) in EXPECTED
setup_logging(args.log) _kid = args.kid keys = [] if args.rsa_file: keys.append(RSAKey(key=import_rsa_key_from_file(args.rsa_file), kid=_kid)) if args.hmac_key: keys.append(SYMKey(key=args.hmac_key)) if args.jwk: kspec = json.loads(open(args.jwk).read()) keys.append(keyrep(kspec)) if args.jwks: _k = KEYS() _k.load_jwks(open(args.jwks).read()) keys.extend(_k._keys) if not keys: exit(-1) if args.msg_file: message = open(args.msg_file).read().strip("\n") elif args.message == "-": message = sys.stdin.read() else: message = args.message if args.sign: _msg = sign(message, keys, args.alg)
setup_logging(args.log) _kid = args.kid keys = [] if args.rsa_file: keys.append(RSAKey(key=import_rsa_key_from_file(args.rsa_file), kid=_kid)) if args.hmac_key: keys.append(SYMKey(key=args.hmac_key)) if args.jwk: kspec = json.loads(open(args.jwk).read()) keys.append(keyrep(kspec)) if args.jwks: _k = KEYS() _k.load_jwks(open(args.jwks).read()) keys.extend(_k._keys) if args.jwks_url: _k = KEYS() _k.load_from_url(args.jwks_url, False) keys.extend(_k._keys) if not keys: exit(-1) if args.msg_file: message = open(args.msg_file).read().strip("\n") elif args.message == "-": message = sys.stdin.read()
def test_pick(): keys = KEYS() keys.load_dict(JWK2) _jws = JWS("foobar", alg="RS256", kid="MnC_VZcATfM5pOYiJHMba9goEKY") _keys = _jws._pick_keys(keys, use="sig") assert len(_keys) == 1
def jwks(self): keys = KEYS() keys.load_from_url(self.oidc_config['jwks_uri']) return keys
# (signature or encryption) # # A key jar can also be created with the method build_keyjar specifying a key_conf containing a list of keys to be # created, with their type, name and usage (encryption of signature) key = create_and_store_rsa_key_pair("foo", size=4096) key2 = create_and_store_rsa_key_pair("foo2", size=4096) rsa = RSAKey().load_key(key) print "--- JWK ---" print json.dumps(rsa.serialize(), sort_keys=True, indent=4, separators=(',', ': ')) print ######################################################## keys = KEYS() keys.wrap_add(key, use="sig", kid="rsa1") keys.wrap_add(key2, use="enc", kid="rsa1") print "--- JWKS---" print keys.dump_jwks() print ######################################################## key_conf = [ {"type": "RSA", "name": "rsa_key", "use": ["enc", "sig"]}, {"type": "EC", "name": "elliptic_curve_1", "crv": "P-256", "use": ["sig"]}, {"type": "EC", "name": "elliptic_curve_2", "crv": "P-256", "use": ["enc"]} ] jwks, keyjar, kdd = build_keyjar(key_conf, "m%d", None, None)
def load_keys(self): # load the jwk set. jwks = KEYS() jwks.load_jwks(self.get_jwks_data()) return jwks
def test_thumbprint(): keyl = KEYS() keyl.load_dict(JWKS) for key in keyl: txt = key.thumbprint("SHA-256") assert b64e(txt) in EXPECTED
print("--- JWK (public) ----") print(json.dumps(ser_rsa, sort_keys=True, indent=4, separators=(',', ': '))) print() # and this will give you the serialization of the private key ser_rsa = rsa.serialize(private=True) print("--- JWK (private) ----") print(json.dumps(ser_rsa, sort_keys=True, indent=4, separators=(',', ': '))) print() # ============================================================================ # And now for the JWKS keys = KEYS() keys.wrap_add(key, use="sig", kid="rsa1") print("--- JWKS ----") print(keys.dump_jwks()) # Build a number of keys from a specification and place them in a keyjar key_conf = [ {"type": "RSA", "name": "rsa_key", "use": ["enc", "sig"]}, {"type": "EC", "crv": "P-256", "use": ["sig"]}, {"type": "EC", "crv": "P-256", "use": ["enc"]} ] # The function return a set of representations of the keys that was # created. # jwks: a JWKS representation