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 _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 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 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 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 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_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)
class JWT_Verification(): def __init__(self, url): self.SIGKEYS = KEYS() self.url = url 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): headers = { 'content-type': "application/json", "cache-control": "no-cache" } res = requests.get(self.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_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_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 test_thumbprint(): keyl = KEYS() keyl.load_dict(JWKS) for key in keyl: txt = key.thumbprint('SHA-256') assert b64e(txt) in EXPECTED
def test_pick_no_use(): keys = KEYS() keys.load_dict(JWKS0) _jws = JWS("foobar", alg="RS256", kid="rsa1") _keys = _jws.pick_keys(keys, use="sig") assert len(_keys) == 1
def test_pick_wrong_alg(): keys = KEYS() keys.load_dict(JWKS0) _jws = JWS("foobar", alg="RS256", kid="rsa1") # should be RSA256 _keys = _jws.pick_keys(keys, use="sig") assert len(_keys) == 0
def test_loads_1(): # DEFAULT # 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" # } # ] # } # VERIZON # jwk = { # "keys":[ # {"kid":"bb35ca40-5ca3-11e9-b9b3-8917f1aeb6fd","kty":"RSA","alg":"RS256","n":"op8E8XUgEjCgB1mimQ49-2WRjAedPW1gSU5b_M84miW1MnoXGlKHa9knBXRWFT-YU8Eq8O15ltwz5TvdorPcvwjx7CE41ikAKwjvNK-Qvn09lQjKiixStll_nNn-5y1TQ0OF44N8MVlApBni44cqeaZvJ-37oCftfd4gxv7hSB95lzI2Ax7YvsacwPbf8Lm5pm00rede21YZNVXq9DbOFB4F4SFQM0oL3aPoG5oyXG6lsDsoSc-qpvXZXOwBsc4bQmqx1SL_BTkLdGuMF7aKosRJ8BNwnJmQg0HvrU0oy4vR7vAiJW_mquol8cS8Nuxp0RHXRT7Xe8DJzxo_245Q1w","e":"AQAB","use":"enc"}, # {"kid":"zhBofbZw+jkZZjXs28fGfzxZgM8=","kty":"RSA","alg":"RS256","n":"AKNbl89eP6B8kZATNSPe3-OZ3esLx31hjX-dakHtPwXCAaCKqJFwjwKdxyRuPdsVG-8Dbk3PGhk26aJrSE93EpxeqmQqxNPMeD-N0_8pjkuVYWwPIQ_ts2iTiWOVn7wzlE4ASfvupqOR5pjuYMWNo_pd4L7QNjUCKoAt9H11HMyiP-6roo_EYgX4AH7OAhfUMncYsopWhkW_ze9z8wTXc8BAEgDmt8zFCez1CtqJB_MlSBUGDgk8oHYDsHKmx05baBaOBQ8LRGP5SULSbRtu34eLFootBIn0FvUZSnwTiSpbaHHRgWrMOVm07oSLWBuO3h_bj38zBuuqqVsAK8YuyoE","e":"AQAB","use":"sig"} # ] # } # TMO jwk = { "keys": [ { "kty": "RSA", "kid": "pre.ccidauth.uxsidmwsdfjhaaa9324asdf", "alg": "RS256", "use": "sig", "e": "AQAB", "n": "<TBD>", "x5c": [ "MIIGzTCCBbWgAwIBAgIQbxp6cPZw0VIAAAAAUPAT7zANBgkqhkiG9w0BAQsFADCBujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxSzAeFw0xOTA0MDkyMzI4MDNaFw0yMDA0MDkyMzU4MDNaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMREwDwYDVQQHEwhCZWxsZXZ1ZTEbMBkGA1UEChMSVC1Nb2JpbGUgVVNBLCBJbmMuMSIwIAYDVQQDExlwcmUuY2NpZGF1dGgudC1tb2JpbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyxpk9WYh4G7hIU02uwyPEwMG+yYsGG9SzXlVRY8KH2MRxHKAkUlxxNfaBUmyT5I41fvGLp95I2SXSLrLr2duBrB99w5AK889kZP92ueJA38C3UEpcOLx9AZmkNgqmqgEPu8nUVS4xAeArt5yOU3bQ0yN3Q/V1YlEYYLWSKgQIlYhH6V0MD3j62PcAlQ/GX/WhAZjig69cqpxJH4jCtXyq+qUUcDRyj70vQ65ufuTB3B26wOqpvxUuoTgP6Y4D2EiewRuTQfwrkKUQxYkd45RJW4K8vZ7t6AYWDVO/S8hxoafYM0rSP1Bt30yzE/t/b9zfvZf1/uqCNmW4xW9nEelQwIDAQABo4IDEDCCAwwwJAYDVR0RBB0wG4IZcHJlLmNjaWRhdXRoLnQtbW9iaWxlLmNvbTCCAXwGCisGAQQB1nkCBAIEggFsBIIBaAFmAHYAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFqBImPdAAABAMARzBFAiAym5whxc8RjbWLgz5qaMJ5FTG9FsVZcPxf1AhtAO1ntgIhAKnO4sU8lOm7ragqB4M8yaWkVQjC14H952/i/NjTVSrMAHUAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0wwAAAFqBImPjQAABAMARjBEAiBhm8fdDnWScIqtY4GEAFpcVPwUhWfJkJ1P0QuJBRmUuAIgfWlSX2nBnqZsFQs2ZUMF1Vl6B/QnG1r1ZIG4ifjotLQAdQC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAWoEiY+dAAAEAwBGMEQCIGswT6FCU7TkIpbi+vxgmcdbHCOxL585RmgblqfyBgAAAiBLGM6HhCRWu8DHfA1njRBzu8nxjq676OnisKScLYujszAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZW50cnVzdC5uZXQvbGV2ZWwxay5jcmwwSwYDVR0gBEQwQjA2BgpghkgBhvpsCgEFMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBhMAgGBmeBDAECAjBoBggrBgEFBQcBAQRcMFowIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmVudHJ1c3QubmV0MDMGCCsGAQUFBzAChidodHRwOi8vYWlhLmVudHJ1c3QubmV0L2wxay1jaGFpbjI1Ni5jZXIwHwYDVR0jBBgwFoAUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHQYDVR0OBBYEFN9H146H/vfPoSCHHAZjmtAE4Jz2MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAIyJSYIwWwV26dxtznWfk4hKxzht4c7e3et4akBsoOjTo8vFKyz43LSp2csYIgdNZjkJhu+a49hJ5avpByBlQl5iB0XPNtF3AUTa2OW3pZJnG/QHeYt3CvAOYCjms9lhm1hwxQE4QhwsMfCuxXqrlcOJxJkOqeXZ6Xcw93O9yiCnvE2HLdx3RgroWnRV6PN5Nup0lNp8nfmREZdwRaT/n5yzebNc7d+PuIDlh9R/uihNEGi0/5nU4BNXnhOJuBWLQ2qHoson4EUExAArkqM1zw+M+EnZMhm0MSRIwP7A/f4kpVFPZEnmGUeVN7BdxjTxuswM5jKH//+V3xhvGjOzZhY=" ] }, # { # "kty": "RSA", # "kid": "3dgt0ku4be052xaq", # "alg": "RS256", # "use": "enc", # "e": "AQAB", # "n": "p-MEbsQE4N1a1gXiobp4Le-KyL1FyRvVoxvR3Jf5HZeVvF2f6uuIi2g66fp_R7DOv-EoBWE1FIIo_X5qhArz9jYN9sCfDqyEBrwbhuy9lzfpPWHliaQUG8K1lfR8JZoxNIFJJlbifZ_rvG2pmZIrS7Iyp7QRWwwl_tVJRNX-mLRIBJ85fkNaSnA5zSeJgVw2Zw_9iFdCotfDmtUPJKlyUMoNWrc-1PdlYuqjTAcEUk-7HiEqA_Hx_eCBeQeUmsyDlKDf0KwGt5Wc96ymFLbkiKLIVdXANF4fT-qRl4B6W8SmASepTaewOu2MKO9iN-RknG0TRHzvuGiembfU31jdUw" # }, # { # "kty": "RSA", # "kid": "kid_selfsigned", # "alg": "RS256", # "use": "sig", # "e": "AQAB", # "n": "rMho5Lhsz5cyVQQuVDXZd7Kj1zKceam1vrWxEZry19T5Bs7TBCTqe87XybQ0HA6jjfyc5PJqSlE7isyxa2ECmIUKQc_esZtvy-nllHqekEqSy134Kfm-PdcV0yTE-L9mzm-wHR0z8hBzeFNkml2cCLjcULx3uAc5xzcN1vVXKBmmeytkEAcHfS8WmqySRIYPFdWlMzvL5tnnK2O_p4lS9gCJnL5YtB231mQBQ-VT080iKYEJrXKOX46VtOEhDF-epz9pg10rUHmX2kVu87GoXHV3rqSH3aYB65SYOCfG7Z68m_3-OJX3BeKbX25qtOHoLrMn5Ql_aJE7FI1-cuiZ4w" # } ] } # ERROR ONLY on First key # ValueError: Invalid RSA public exponent keys = KEYS() keys.load_dict(jwk) print(keys)
def test_thumbprint(): keyl = KEYS() keyl.load_dict(JWKS) for key in keyl: txt = key.thumbprint("SHA-256") assert b64e(txt) in EXPECTED
"-b112-36a304b66dad/v2.0/", "kid": "dEtpjbEvbhfgwUI-bdK5xAU_9UQ", "kty": "RSA", "n": "x7HNcD9ZxTFRaAgZ7-gdYLkgQua3zvQseqBJIt8Uq3MimInMZoE9QGQeSML7qZPlowb5BUakdLI70ayM4vN36--0ht8-oCHhl8YjGFQkU-Iv2yahWHEP-1EK6eOEYu6INQP9Lk0HMk3QViLwshwb-KXVD02jdmX2HNdYJdPyc0c", "use": "sig", "x5c": [ "MIICWzCCAcSgAwIBAgIJAL3MzqqEFMYjMA0GCSqGSIb3DQEBBQUAMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleTAeFw0xMzExMTExOTA1MDJaFw0xOTExMTAxOTA1MDJaMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx7HNcD9ZxTFRaAgZ7+gdYLkgQua3zvQseqBJIt8Uq3MimInMZoE9QGQeSML7qZPlowb5BUakdLI70ayM4vN36++0ht8+oCHhl8YjGFQkU+Iv2yahWHEP+1EK6eOEYu6INQP9Lk0HMk3QViLwshwb+KXVD02jdmX2HNdYJdPyc0cCAwEAAaOBijCBhzAdBgNVHQ4EFgQULR0aj9AtiNMgqIY8ZyXZGsHcJ5gwWQYDVR0jBFIwUIAULR0aj9AtiNMgqIY8ZyXZGsHcJ5ihLaQrMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibGljIEtleYIJAL3MzqqEFMYjMAsGA1UdDwQEAwIBxjANBgkqhkiG9w0BAQUFAAOBgQBshrsF9yls4ArxOKqXdQPDgHrbynZL8m1iinLI4TeSfmTCDevXVBJrQ6SgDkihl3aCj74IEte2MWN78sHvLLTWTAkiQSlGf1Zb0durw+OvlunQ2AKbK79Qv0Q+wwGuK+oymWc3GSdP1wZqk9dhrQxb3FtdU2tMke01QTut6wr7ig==" ], "x5t": "dEtpjbEvbhfgwUI-bdK5xAU_9UQ" } ] } 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
"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