def test_jwe_decrypt_legacy_v1_without_temp_var_expiry(self): expiry_seconds = 10 claims = {jose.CLAIM_ISSUED_AT: int(time()) - 15} jwe = legacy_encrypt(claims, rsa_pub_key) legacy_patch = mock.patch.object( jose, 'legacy_decrypt', wraps=jose.legacy_decrypt ) spec_patch = mock.patch.object( jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt ) with legacy_patch as legacy_mock, spec_patch as spec_mock: with self.assertRaises(jose.Expired) as expiry_error: jose.decrypt(jwe, rsa_priv_key, expiry_seconds=expiry_seconds) expiration_time = claims[jose.CLAIM_ISSUED_AT] + expiry_seconds self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 0) self.assertEqual( expiry_error.exception.message, 'Token expired at {}'.format( jose._format_timestamp(expiration_time) ) )
def test_jwe_decrypt_legacy_v1_without_temp_ver_not_yet_valid(self): # not valid for another hour. claim_not_before = int(time()) + 3600 claims = {jose.CLAIM_NOT_BEFORE: claim_not_before} jwe = legacy_encrypt(claims, rsa_pub_key) legacy_patch = mock.patch.object( jose, 'legacy_decrypt', wraps=jose.legacy_decrypt ) spec_patch = mock.patch.object( jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt ) with legacy_patch as legacy_mock, spec_patch as spec_mock: with self.assertRaises(jose.NotYetValid) as not_valid_error: jose.decrypt(jwe, rsa_priv_key) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 0) self.assertEqual( not_valid_error.exception.message, 'Token not valid until {}'.format( jose._format_timestamp(claim_not_before) ) )
def test_jwe_decrypt_legacy_v1_without_temp_ver_incorrect_jwk(self): jwk_for_encrypt = {'k': PRIVATE_KEY} legacy_legacy_temp_ver = jose.serialize_compact( legacy_encrypt(claims, jwk_for_encrypt) ) jwk_for_decrypt = {'k': RSA.generate(2048).exportKey('PEM')} legacy_patch = mock.patch.object( jose, 'legacy_decrypt', wraps=jose.legacy_decrypt ) spec_patch = mock.patch.object( jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt ) with legacy_patch as legacy_mock, spec_patch as spec_mock: with self.assertRaises(jose.Error) as decryption_error: jose.decrypt( jose.deserialize_compact(legacy_legacy_temp_ver), jwk_for_decrypt) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 1) self.assertEqual(decryption_error.exception.message, "Incorrect decryption.")
def test_jwe(self): bad_key = {'k': RSA.generate(2048).exportKey('PEM')} for (alg, jwk), enc in product(self.algs, self.encs): jwe = jose.encrypt(claims, rsa_pub_key, enc=enc, alg=alg) # make sure the body can't be loaded as json (should be encrypted) try: json.loads(jose.b64decode_url(jwe.ciphertext)) self.fail() except ValueError: pass token = jose.serialize_compact(jwe) jwt = jose.decrypt(jose.deserialize_compact(token), rsa_priv_key) self.assertNotIn(jose._TEMP_VER_KEY, claims) self.assertEqual(jwt.claims, claims) # invalid key try: jose.decrypt(jose.deserialize_compact(token), bad_key) self.fail() except jose.Error as e: self.assertEqual(e.message, 'Incorrect decryption.')
def test_jwe_direct_encryption(self): symmetric_key = "tisasymmetrickey" jwe = jose.encrypt(claims, "", alg = "dir",enc="A128CBC-HS256", dir_key = symmetric_key) # make sure the body can't be loaded as json (should be encrypted) try: json.loads(jose.b64decode_url(jwe.ciphertext)) self.fail() except ValueError: pass token = jose.serialize_compact(jwe) jwt = jose.decrypt(jose.deserialize_compact(token),"", dir_key = symmetric_key) self.assertNotIn(jose._TEMP_VER_KEY, claims) self.assertEqual(jwt.claims, claims) # invalid key badkey = "1234123412341234" try: jose.decrypt(jose.deserialize_compact(token), '', dir_key=badkey) self.fail() except jose.Error as e: self.assertEqual(e.message, 'Mismatched authentication tags')
def test_jwe_no_error_with_iat_claim(self): claims = {jose.CLAIM_ISSUED_AT: int(time()) - 15} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) jose.decrypt(jose.deserialize_compact(et), rsa_priv_key, expiry_seconds=20)
def test_jwe_invalid_base64(self): try: jose.decrypt('aaa', rsa_priv_key) self.fail() # expecting error due to invalid base64 except jose.Error as e: pass self.assertEquals(e.args[0], 'Unable to decode base64: Incorrect padding')
def test_decrypt_invalid_compression_error(self): jwe = jose.encrypt(claims, rsa_pub_key, compression='DEF') header = jose.b64encode_url('{"alg": "RSA-OAEP", ' '"enc": "A128CBC-HS256", "zip": "BAD"}') try: jose.decrypt(jose.JWE(*((header,) + (jwe[1:]))), rsa_priv_key) self.fail() except ValueError as e: self.assertEqual(e.message, 'Unsupported compression algorithm: BAD')
def test_jwe_invalid_base64(self): try: jose.decrypt('aaa', rsa_priv_key) self.fail() # expecting error due to invalid base64 except jose.Error as e: pass self.assertEquals( e.args[0], 'Unable to decode base64: Incorrect padding' )
def test_jwe_not_yet_valid_error_with_nbf_claim(self): claims = {jose.CLAIM_NOT_BEFORE: int(time()) + 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() # expecting not valid yet except jose.NotYetValid as e: pass self.assertEquals( e.args[0], 'Token not valid until {}'.format( jose._format_timestamp(claims[jose.CLAIM_NOT_BEFORE])))
def test_jwe_expired_error_with_exp_claim(self): claims = {jose.CLAIM_EXPIRATION_TIME: int(time()) - 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() # expecting expired token except jose.Expired as e: pass self.assertEquals( e.args[0], 'Token expired at {}'.format( jose._format_timestamp(claims[jose.CLAIM_EXPIRATION_TIME])))
def _decrypt(self, request): """ Decrypt a JOSE encrypted request. :param request: Request to parse :type request: str :rtype: bool or jose.JWS """ jwe = jose.deserialize_compact(request.replace("\n", '')) decrypted = None decr_key = self._config.keys.private_key if not decr_key: self._logger.error("No asymmetric private key (named '_private') found in the keystore") return False self._logger.debug("Trying to decrypt request with key {!r}".format(decr_key)) try: decrypted = jose.decrypt(jwe, decr_key.jwk, expiry_seconds = decr_key.expiry_seconds) self._logger.debug("Decrypted {!r}".format(decrypted)) except jose.Expired as ex: self._logger.warning("Request encrypted with key {!r} has expired: {!r}".format(decr_key, ex)) except jose.Error as ex: self._logger.warning("Failed decrypt with key {!r}: {!r}".format(decr_key, ex)) raise EduIDAPIError('Could not decrypt request') if not 'v1' in decrypted.claims: self._logger.error("No 'v1' in decrypted claims: {!r}".format(decrypted)) return False to_verify = jose.deserialize_compact(decrypted.claims['v1']) #logger.debug("Decrypted claims to verify: {!r}".format(to_verify)) return to_verify
def test_jwe_decrypt_legacy_v1_without_temp_ver(self): jwk = {'k': PRIVATE_KEY} legacy_patch = mock.patch.object( jose, 'legacy_decrypt', wraps=jose.legacy_decrypt ) spec_patch = mock.patch.object( jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt ) legacy_legacy_temp_ver = jose.serialize_compact( legacy_encrypt(claims, jwk) ) with legacy_patch as legacy_mock, spec_patch as spec_mock: jwt = jose.decrypt( jose.deserialize_compact(legacy_legacy_temp_ver), jwk) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 0) self.assertEqual(jwt.claims, claims) expected_header = { 'alg': 'RSA-OAEP', 'enc': 'A128CBC-HS256', } self.assertEqual(jwt.header, expected_header) self.assertNotIn('__v', jwt.header)
def test_jwe_not_yet_valid_error_with_nbf_claim(self): claims = {jose.CLAIM_NOT_BEFORE: int(time()) + 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() # expecting not valid yet except jose.NotYetValid as e: pass self.assertEquals( e.args[0], 'Token not valid until {}'.format( jose._format_timestamp(claims[jose.CLAIM_NOT_BEFORE]) ) )
def test_jwe_expired_error_with_exp_claim(self): claims = {jose.CLAIM_EXPIRATION_TIME: int(time()) - 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() # expecting expired token except jose.Expired as e: pass self.assertEquals( e.args[0], 'Token expired at {}'.format( jose._format_timestamp(claims[jose.CLAIM_EXPIRATION_TIME]) ) )
def test_jwe(self): bad_key = {'k': RSA.generate(2048).exportKey('PEM')} jwe = legacy_encrypt(claims, rsa_pub_key) token = jose.serialize_compact(jwe) jwt = jose.decrypt(jose.deserialize_compact(token), rsa_priv_key) self.assertEqual(jwt.claims, claims) self.assertNotIn(jose._TEMP_VER_KEY, claims) # invalid key try: jose.decrypt(jose.deserialize_compact(token), bad_key) self.fail() except jose.Error as e: self.assertEqual(e.message, 'Incorrect decryption.')
def test_jwe_adata(self): adata = '42' for (alg, jwk), enc in product(self.algs, self.encs): et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key, adata=adata)) jwt = jose.decrypt(jose.deserialize_compact(et), rsa_priv_key, adata=adata) # make sure signaures don't match when adata isn't passed in try: hdr, dt = jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() except ValueError as e: self.assertEqual(e.message, 'Mismatched authentication tags') self.assertEqual(jwt.claims, claims)
def test_jwe_expired_error_with_iat_claim(self): expiry_seconds = 10 claims = {jose.CLAIM_ISSUED_AT: int(time()) - 15} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key, expiry_seconds=expiry_seconds) self.fail() # expecting expired token except jose.Expired as e: pass expiration_time = claims[jose.CLAIM_ISSUED_AT] + expiry_seconds self.assertEquals( e.args[0], 'Token expired at {}'.format( jose._format_timestamp(expiration_time)))
def _decrypt_and_verify(self, plaintext, decr_key, signing_key, alg = 'RS256'): jwe = jose.deserialize_compact(plaintext.replace("\n", '')) decrypted = jose.decrypt(jwe, decr_key) if not 'v1' in decrypted.claims: return False to_verify = jose.deserialize_compact(decrypted.claims['v1']) jwt = jose.verify(to_verify, signing_key, alg=alg) return jwt
def test_jwe_adata(self): adata = '42' for (alg, jwk), enc in product(self.algs, self.encs): et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key, adata=adata)) jwt = jose.decrypt(jose.deserialize_compact(et), rsa_priv_key, adata=adata) # make sure signaures don't match when adata isn't passed in try: hdr, dt = jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() except jose.Error as e: self.assertEqual(e.message, 'Mismatched authentication tags') self.assertEqual(jwt.claims, claims)
def update(): resp={} content = request.data jwt = jose.decrypt(jose.deserialize_compact(content), priv_jwk) try: ipaddr = jwt[1]['ipaddr'] regid = jwt[1]['hostname'] except KeyError, e: return 'KeyError', 400
def test_jwe_decrypt_compliant_incorrect_jwk(self): jwk_for_decrypt = {'k': RSA.generate(2048).exportKey('PEM')} legacy_patch = mock.patch.object(jose, 'legacy_decrypt', wraps=jose.legacy_decrypt) spec_patch = mock.patch.object(jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt) with legacy_patch as legacy_mock, spec_patch as spec_mock: with self.assertRaises(jose.Error) as decryption_error: jose.decrypt(jose.deserialize_compact(SPEC_COMPLIANT_TOKEN), jwk_for_decrypt) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 1) self.assertEqual(decryption_error.exception.message, "Incorrect decryption.")
def test_jwe_add_header(self): add_header = {'foo': 'bar'} for (alg, jwk), enc in product(self.algs, self.encs): et = jose.serialize_compact( jose.encrypt(claims, rsa_pub_key, add_header=add_header)) jwt = jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.assertEqual(jwt.header['foo'], add_header['foo'])
def test_jwe_add_header(self): add_header = {'foo': 'bar'} for (alg, jwk), enc in product(self.algs, self.encs): et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key, add_header=add_header)) jwt = jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.assertEqual(jwt.header['foo'], add_header['foo'])
def test_jwe_expired_error_with_iat_claim(self): expiry_seconds = 10 claims = {jose.CLAIM_ISSUED_AT: int(time()) - 15} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key, expiry_seconds=expiry_seconds) self.fail() # expecting expired token except jose.Expired as e: pass expiration_time = claims[jose.CLAIM_ISSUED_AT] + expiry_seconds self.assertEquals( e.args[0], 'Token expired at {}'.format( jose._format_timestamp(expiration_time) ) )
def test_jwe_invalid_dates_error(self): claims = {'exp': time() - 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() # expecting expired token except ValueError: pass claims = {'nbf': time() + 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) try: jose.decrypt(jose.deserialize_compact(et), rsa_priv_key) self.fail() # expecting not valid yet except ValueError: pass
def test_version1(self): bad_key = {'k': RSA.generate(2048).exportKey('PEM')} jwe = legacy_encrypt(claims, rsa_pub_key, version=1) token = jose.serialize_compact(jwe) jwt = jose.decrypt(jose.deserialize_compact(token), rsa_priv_key) self.assertEqual(jwt.claims, claims) self.assertEqual(jwt.header.get(jose._TEMP_VER_KEY), 1)
def test_jwe_decrypt_compliant_incorrect_jwk(self): jwk_for_decrypt = {'k': RSA.generate(2048).exportKey('PEM')} legacy_patch = mock.patch.object( jose, 'legacy_decrypt', wraps=jose.legacy_decrypt ) spec_patch = mock.patch.object( jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt ) with legacy_patch as legacy_mock, spec_patch as spec_mock: with self.assertRaises(jose.Error) as decryption_error: jose.decrypt( jose.deserialize_compact(SPEC_COMPLIANT_TOKEN), jwk_for_decrypt) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 1) self.assertEqual(decryption_error.exception.message, "Incorrect decryption.")
def _decrypt_and_verify(self, plaintext, decr_key, signing_key, alg='RS256'): jwe = jose.deserialize_compact(plaintext.replace("\n", '')) decrypted = jose.decrypt(jwe, decr_key) if not 'v1' in decrypted.claims: return False to_verify = jose.deserialize_compact(decrypted.claims['v1']) jwt = jose.verify(to_verify, signing_key, alg=alg) return jwt
def decrypt_fluffy(jwe, key): print '\n*****************************' print 'Performing Decryption on ' + jwe print '*****************************' print "OPENING FILE" f = open(jwe, "r") data = f.read() f.close() os.remove(jwe) dec = jose.decrypt(jose.deserialize_compact(data), '', dir_key=key) out = json.dumps(dec, indent=4, separators=(', ', ': '), sort_keys=True) print out print '*****************************'
def getCert_v03(): #register with ddns logger.debug('Registering') resp={} content = request.data jwt = jose.decrypt(jose.deserialize_compact(content), priv_jwk) try: ipaddress = jwt[1]['ipaddr'] hostname = jwt[1]['hostname'] alg = jwt[1]['alg'] secret = jwt[1]['secret'] privkey = jwt[1]['privkey'] #to be used with LE except KeyError, e: return 'KeyError', 400
def test_jwe_decrypt_legacy_v1(self): jwk = {'k': PRIVATE_KEY} legacy_patch = mock.patch.object(jose, 'legacy_decrypt', wraps=jose.legacy_decrypt) spec_patch = mock.patch.object(jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt) with legacy_patch as legacy_mock, spec_patch as spec_mock: jwt = jose.decrypt(jose.deserialize_compact(LEGACY_V1_TOKEN), jwk) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 0) self.assertEqual(jwt.claims, claims) expected_header = {'alg': 'RSA-OAEP', 'enc': 'A128CBC-HS256', '__v': 1} self.assertEqual(jwt.header, expected_header)
def test_jwe_compression(self): local_claims = copy(claims) for v in xrange(1000): local_claims['dummy_' + str(v)] = '0' * 100 jwe = jose.serialize_compact(jose.encrypt(local_claims, rsa_pub_key)) _, _, _, uncompressed_ciphertext, _ = jwe.split('.') jwe = jose.serialize_compact(jose.encrypt(local_claims, rsa_pub_key, compression='DEF')) _, _, _, compressed_ciphertext, _ = jwe.split('.') self.assertTrue(len(compressed_ciphertext) < len(uncompressed_ciphertext)) jwt = jose.decrypt(jose.deserialize_compact(jwe), rsa_priv_key) self.assertEqual(jwt.claims, local_claims)
def test_jwe_compression(self): local_claims = copy(claims) for v in xrange(1000): local_claims['dummy_' + str(v)] = '0' * 100 jwe = jose.serialize_compact(jose.encrypt(local_claims, rsa_pub_key)) _, _, _, uncompressed_ciphertext, _ = jwe.split('.') jwe = jose.serialize_compact( jose.encrypt(local_claims, rsa_pub_key, compression='DEF')) _, _, _, compressed_ciphertext, _ = jwe.split('.') self.assertTrue( len(compressed_ciphertext) < len(uncompressed_ciphertext)) jwt = jose.decrypt(jose.deserialize_compact(jwe), rsa_priv_key) self.assertEqual(jwt.claims, local_claims)
def decrypt_response(self, ciphertext=None, return_jwt=False): """ Decrypt the response returned from send_request. :param ciphertext: Ciphertext to decrypt. If not supplied the last request response is used. :param return_jwt: Return the whole JOSE JWT or just the claims :type ciphertext: None | str | unicode :type return_jwt: bool :return: Decrypted result :rtype: dict | jose.JWT """ if ciphertext is None: ciphertext = self._request_result.text jwe = jose.deserialize_compact(ciphertext.replace("\n", '')) priv_key = self._config.keys.private_key if not priv_key.keytype == 'jose': raise EduIDAPIError("Non-jose private key unusuable with decrypt_response") decrypted = jose.decrypt(jwe, priv_key.jwk) if not 'v1' in decrypted.claims: self._logger.error("No 'v1' in decrypted claims: {!r}\n\n".format(decrypted)) raise EduIDAPIError("No 'v1' in decrypted claims") to_verify = jose.deserialize_compact(decrypted.claims['v1']) jwt = jose.verify(to_verify, self._api_key.jwk, alg = self._config.jose_alg) self._logger.debug("Good signature on response to request using key: {!r}".format( self._api_key.jwk )) if 'nonce' in self._claims: # there was a nonce in the request, verify it is also present in the response if not 'nonce' in jwt.claims: self._logger.warning("Nonce was present in request, but not in response:\n{!r}".format( jwt.claims )) raise EduIDAPIError("Request-Response nonce validation error") if jwt.claims['nonce'] != self._claims['nonce']: self._logger.warning("Response nonce {!r} does not match expected {!r}".format( jwt.claims['nonce'], self._claims['nonce'] )) if return_jwt: return jwt return jwt.claims
def test_jwe_decrypt_legacy_v1(self): jwk = {'k': PRIVATE_KEY} legacy_patch = mock.patch.object( jose, 'legacy_decrypt', wraps=jose.legacy_decrypt ) spec_patch = mock.patch.object( jose, 'spec_compliant_decrypt', wraps=jose.spec_compliant_decrypt ) with legacy_patch as legacy_mock, spec_patch as spec_mock: jwt = jose.decrypt(jose.deserialize_compact(LEGACY_V1_TOKEN), jwk) self.assertEqual(legacy_mock.call_count, 1) self.assertEqual(spec_mock.call_count, 0) self.assertEqual(jwt.claims, claims) expected_header = { 'alg': 'RSA-OAEP', 'enc': 'A128CBC-HS256', '__v': 1 } self.assertEqual(jwt.header, expected_header)
def test_jwe_no_error_with_nbf_claim(self): claims = {jose.CLAIM_NOT_BEFORE: int(time()) - 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) jose.decrypt(jose.deserialize_compact(et), rsa_priv_key)
print "\tWrong token signature! " print "\tError signing token! " e = sys.exc_info()[0] print "Error: %s" % e exit() print "\t< Decrypt information (information, MtB private key) >" print "\t |" try: # JWT(header={u'alg': u'HS256'}, claims={u'iss': u'http://www.example.com', u'sub': 42, u'exp': 1395674427}) header = signed_jws[0] claims = signed_jws[1] # JWE decode secret secret = claims['secret'] # decrypt on the other end using the private key priv_jwk = {'k': mtb_key.exportKey('PEM')} jwe = jose.deserialize_compact(secret) decoded = jose.decrypt(jwe, priv_jwk) # JWT(header={u'alg': u'RSA-OAEP', u'enc': u'A128CBC-HS256'}, # claims={}) print "\t< Decoded information:" + str(decoded) + " >" print "\t |" print "\t END" except: print "\tError encrypting information! " e = sys.exc_info()[0] print "Error: %s" % e exit()
def test_jwe_ignores_expired_token_if_validate_claims_is_false(self): claims = {jose.CLAIM_EXPIRATION_TIME: int(time()) - 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) jose.decrypt(jose.deserialize_compact(et), rsa_priv_key, validate_claims=False)
# JWE ## A.1. "RSA-OAEP" + "AES GCM" key = { "kty":"RSA", "n":"oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw", "e":"AQAB", "d":"kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ" } jwe = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ" jwed = deserialize(jwe) jweb = serialize_msgpack(jwed) dec = jose.decrypt(jweb, [key]) print "OAEP+GCM (fixed) {res} {pt} ({clen} / {blen} / {blen64})".format( res = dec["result"], pt = dec["plaintext"], clen = len(jwe), blen = len(jweb), blen64 = len(b64enc(jweb))) ## A.2. "RSA_1_5" + "AES_128_CBC_HMAC_SHA_256" key = { "kty":"RSA", "n":"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1WlUzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDprecbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBIY2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw", "e":"AQAB", "d":"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-rynq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-KyvjT1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ"
#!/usr/bin/env python import jose from jose.serialize import serialize_compact import json # Compression test plaintext = "Kh" + ("a" * 512) + "n!" jwe_header = {"alg": "A128KW", "enc": "A128GCM", "zip": "DEF"} keys = [{"kty": "oct", "k": "i-ueSNQgcr0q7auC8YUrYg"}] jwe1 = jose.encrypt(jwe_header, keys, plaintext, protect="*") dec1 = jose.decrypt(jwe1, keys) print "Compact JWE with compression:" #print json.dumps(jwe1, indent=4, sort_keys=True) print serialize_compact(jwe1) print print "Decrypted, decompressed JWE:" print dec1 print # Criticality test payload = "Some day you may pass validation. Today is not that day." jws_header1 = {"alg": "HS256", "crit": ["alg"]} jws_header2 = {"alg": "HS256", "true_rings": 1, "crit": ["true_rings"]} keys = [{"kty": "oct", "k": "i-ueSNQgcr0q7auC8YUrYg"}]
def lambda_handler(event, context): """AWS_LAMBDA:auth_gateway Validate the incoming token and produce the principal user identifier associated with the token. Decoding a JWT token inline. :param authorizationToken: Authentication token. :type authorizationToken: str. :param methodArn: Contains information on api_gateway_arn and aws_account_id. :type methodArn: str. :returns: AuthPolicy -- Policy object with access permissions. """ try: #retrieve claims from token jwt_token = jose.decrypt( jose.deserialize_compact(event['authorizationToken']), {'k': PRIVATE_KEY}) except jose.Error as jwt_exception: LOGGER.error(jwt_exception) raise Exception('Unauthorized') now_time = time.time() if now_time - 31104000 > jwt_token.claims['iat'] or\ jwt_token.claims['iss'] != 'medpass-aws' or\ jwt_token.claims['aud'] != 'webclient' or\ jwt_token.claims['type'] not in ['REGISTRATION', 'TEMPORARY', 'USER','PRE-MEDIC', 'MEDIC']: LOGGER.error('Tampered token (iss:' + jwt_token.claims['iss'] + ', aud:' + jwt_token.claims['aud'] + ', type:' + jwt_token.claims['type'] + ').') raise Exception('Unauthorized') #create policy tmp = event['methodArn'].split(':') api_gateway_arn_tmp = tmp[5].split('/') aws_account_id = tmp[4] LOGGER.info(jwt_token.claims['id']) principal_id = jwt_token.claims['id'] policy = AuthPolicy(principal_id, aws_account_id) #adjust policy to user profile if jwt_token.claims['type'] == 'MASTER': policy.allowMethod(HttpVerb.ALL, '/admin/user') if jwt_token.claims['type'] == 'ADMIN': policy.allowMethod(HttpVerb.ALL, '/admin/laboratory/user') policy.allowMethod(HttpVerb.ALL, '/admin/enterprise/user') if jwt_token.claims['type'] == 'REGISTRATION': policy.allowMethod(HttpVerb.POST, '/user') elif jwt_token.claims['type'] == 'TEMPORARY': policy.allowMethod(HttpVerb.OPTIONS, '/medic/temporary') policy.allowMethod(HttpVerb.GET, '/medic/temporary') elif jwt_token.claims['type'] == 'PRE-MEDIC': policy.allowMethod(HttpVerb.OPTIONS, '/medic') policy.allowMethod(HttpVerb.PUT, '/medic') elif jwt_token.claims['type'] == 'USER' or jwt_token.claims[ 'type'] == 'MEDIC': if jwt_token.claims['type'] == 'MEDIC': policy.allowMethod(HttpVerb.POST, '/medic') policy.allowMethod(HttpVerb.PUT, '/medic') policy.allowMethod(HttpVerb.OPTIONS, '/medic') policy.allowMethod(HttpVerb.GET, '/medic/patient') policy.allowMethod(HttpVerb.POST, '/medic/patient') policy.allowMethod(HttpVerb.OPTIONS, '/medic/patient') policy.allowMethod(HttpVerb.ALL, '/medic/calendar') policy.allowMethod(HttpVerb.GET, '/medic/dashboard') policy.allowMethod(HttpVerb.OPTIONS, '/medic/dashboard') policy.allowMethod(HttpVerb.GET, '/user') policy.allowMethod(HttpVerb.PUT, '/user') policy.allowMethod(HttpVerb.OPTIONS, '/user') policy.allowMethod(HttpVerb.POST, '/user/pendencies') policy.allowMethod(HttpVerb.OPTIONS, '/user/pendencies') policy.allowMethod(HttpVerb.POST, '/user/medics') policy.allowMethod(HttpVerb.OPTIONS, '/user/medics') policy.allowMethod(HttpVerb.ALL, '/user/goals') policy.allowMethod(HttpVerb.POST, '/question') policy.allowMethod(HttpVerb.OPTIONS, '/question') policy.allowMethod(HttpVerb.POST, '/question/risk') policy.allowMethod(HttpVerb.OPTIONS, '/question/risk') policy.allowMethod(HttpVerb.POST, '/question/index') policy.allowMethod(HttpVerb.OPTIONS, '/question/index') policy.allowMethod(HttpVerb.POST, '/question/assistance') policy.allowMethod(HttpVerb.OPTIONS, '/question/assistance') policy.allowMethod(HttpVerb.POST, '/question/historic') policy.allowMethod(HttpVerb.OPTIONS, '/question/historic') policy.allowMethod(HttpVerb.POST, '/registration') policy.allowMethod(HttpVerb.OPTIONS, '/registration') policy.allowMethod(HttpVerb.ALL, '/report') policy.allowMethod(HttpVerb.OPTIONS, '/report/pendencies') policy.allowMethod(HttpVerb.POST, '/report/pendencies') policy.allowMethod(HttpVerb.OPTIONS, '/report/risk') policy.allowMethod(HttpVerb.POST, '/report/risk') policy.allowMethod(HttpVerb.OPTIONS, '/report/share') policy.allowMethod(HttpVerb.POST, '/report/share') policy.allowMethod(HttpVerb.GET, '/report/share') policy.allowMethod(HttpVerb.DELETE, '/report/share') policy.allowMethod(HttpVerb.OPTIONS, '/dashboard') policy.allowMethod(HttpVerb.POST, '/dashboard') policy.allowMethod(HttpVerb.OPTIONS, '/forms') policy.allowMethod(HttpVerb.OPTIONS, '/forms/city') policy.allowMethod(HttpVerb.POST, '/forms/city') policy.allowMethod(HttpVerb.ALL, '/assistance') policy.allowMethod(HttpVerb.ALL, '/historic') policy.allowMethod(HttpVerb.ALL, '/web') policy.allowMethod(HttpVerb.OPTIONS, '/mail') policy.allowMethod(HttpVerb.OPTIONS, '/mail/faq') policy.allowMethod(HttpVerb.POST, '/mail/faq') policy.restApiId = api_gateway_arn_tmp[0] policy.region = tmp[3] policy.stage = api_gateway_arn_tmp[1] # Build the policy and exit the function using return output = policy.build() return output
def test_jwe_no_error_with_exp_claim(self): claims = {jose.CLAIM_EXPIRATION_TIME: int(time()) + 5} et = jose.serialize_compact(jose.encrypt(claims, rsa_pub_key)) jose.decrypt(jose.deserialize_compact(et), rsa_priv_key)
#!/usr/bin/env python import jose from jose.serialize import serialize_compact plaintext = "Attack at dawn!" jwe_header = {"alg": "A128KW", "enc": "A128GCM"} jws_header = {"alg": "HS256"} keys = [{"kty": "oct", "k": "i-ueSNQgcr0q7auC8YUrYg"}] # Encrypt into the JSON serialization jwe1 = jose.encrypt(jwe_header, keys, plaintext) dec1 = jose.decrypt(jwe1, keys) print jwe1 print dec1 print # Encrypt into the compact serialization jwe2 = serialize_compact( \ jose.encrypt(jwe_header, keys, plaintext, protect="*")) dec2 = jose.decrypt(jwe2, keys) print jwe2 print dec2 print # Sign into the JSON serialization jws1 = jose.sign(jws_header, keys, plaintext) ver1 = jose.verify(jws1, keys) print jws1 print ver1 print
key = { "kty": "RSA", "n": "oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw", "e": "AQAB", "d": "kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ" } jwe = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ" jwed = deserialize(jwe) jweb = serialize_msgpack(jwed) dec = jose.decrypt(jweb, [key]) print "OAEP+GCM (fixed) {res} {pt} ({clen} / {blen} / {blen64})".format( res=dec["result"], pt=dec["plaintext"], clen=len(jwe), blen=len(jweb), blen64=len(b64enc(jweb))) ## A.2. "RSA_1_5" + "AES_128_CBC_HMAC_SHA_256" key = { "kty": "RSA", "n": "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1WlUzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDprecbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBIY2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw", "e":