def from_jwt(jwt, key): "Returns the decoded claim on success, or throws exception on error" (header, claim, sig) = jwt.split('.') header = jws.utils.from_base64(header) claim = jws.utils.from_base64(claim) jws.verify(header, claim, sig, key, is_json=True) return jws.utils.from_json(claim)
def test_valid_rsa512(self): header = {'alg': 'RS512'} sinput,sig = jws.sign(header, self.payload, self.private) public = self.private.publickey() self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, public)) self.assertTrue(jws.verify(header, None, sig, public, signing_input=sinput))
def test_valid_rsa512(self): header = {'alg': 'RS512'} sinput, sig = jws.sign(header, self.payload, self.private) public = self.private.publickey() self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, public)) self.assertTrue( jws.verify(header, None, sig, public, signing_input=sinput))
def check_dict(data, key): """ raises jws.exceptions.SignatureError if it fails :rtype: dict """ token = data.get('_token') if not token: raise jws.exceptions.SignatureError("missing token!") signature = bytes(token, encoding='utf-8') del data['_token'] data = OrderedDict(sorted(data.items())) jws.verify({'alg': 'HS384'}, data, signature, key) return data
def test_custom_algorithm(self): class F7U12(jws.algos.AlgorithmBase): def __init__(self): pass def sign(self, msg, key): return 'u mad?' + key def verify(self, msg, sig, key): import sys if sys.version < '3': if sig == 'u mad?' + key: return '<trollface>' else: if sig == b'u mad?' + bytes(key, 'UTF-8'): return '<trollface>' raise jws.SignatureError('Y U NO GIVE GOOD SIGNATURE') jws.algos.CUSTOM = [('F7U12', F7U12)] header = {'alg': 'F7U12'} payload = {'some': 'claim'} sig = jws.sign(header, payload, 'wutlol') self.assertEqual(jws.verify(header, payload, sig, 'wutlol'), '<trollface>') self.assertRaises(jws.SignatureError, jws.verify, header, payload, sig, 'raaaaage')
def test_valid_ecdsa512(self): key = self.sk512 header = {'alg': 'ES512'} sinput, sig = jws.sign(header, self.payload, key) self.assertTrue(len(sig) > 0) self.assertTrue( jws.verify(header, self.payload, sig, key.get_verifying_key()))
def verify_data(payload, sig, vk = vk): header = { 'alg': 'ES256' } try: verified = jws.verify(header, payload, sig, vk) except jws.SignatureError: print("Validation Error") return False return verified
def is_jose_sig_valid(b64_jpayload, jose_sig, vk_pem): jpayload = b64url_dec(b64_jpayload, MalformedSignatureError) b64_jheader = dget(jose_sig, 'protected', MalformedSignatureError) jheader = b64url_dec(b64_jheader, MalformedSignatureError) b64_sig = dget(jose_sig, 'signature', MalformedSignatureError) sig_der = b64url_dec(b64_sig, MalformedSignatureError) vk = VerifyingKey.from_pem(vk_pem) vk_order = vk.curve.order b64_sig_string = base64url_encode(sig_der_to_string(sig_der, vk_order)) try: jws.verify(jheader, jpayload, b64_sig_string, vk, is_json=True) return True except jws.SignatureError: return False
def is_jws_sig_valid(b64_jws_sig, vk_pem): parts = b64_jws_sig.split('.') if len(parts) != 3: raise MalformedSignatureError # Extract parts to verify signature jheader_b64, jbody_b64, sig_der_b64 = parts jheader = b64url_dec(jheader_b64) jbody = b64url_dec(jbody_b64) sig_der = b64url_dec(sig_der_b64) vk = VerifyingKey.from_pem(vk_pem) vk_order = vk.curve.order sig_string_b64 = base64url_encode(sig_der_to_string(sig_der, vk_order)) try: jws.verify(jheader, jbody, sig_string_b64, vk, is_json=True) return True except jws.SignatureError: return False
def verify(sjws, pub_pem): sjws = json.loads(sjws) pub_pem = json.loads(pub_pem.replace('\n', '\\n')) if pub_pem.startswith("-----BEGIN"): pub_key = RSA.importKey(pub_pem) else: pub_key = pub_pem header, payload, signature = sjws.split('.') header = jws.utils.from_base64(str(header)) payload = jws.utils.from_base64(str(payload)) if not jws.verify(header, payload, str(signature), pub_key, True): raise "failed to verify signature" sys.stdout.write(payload)
def test_custom_algorithm(self): class F7U12(jws.algos.AlgorithmBase): def __init__(self): pass def sign(self, msg, key): return 'u mad?' + key def verify(self, msg, sig, key): if sig == 'u mad?' + key: return '<trollface>' raise jws.SignatureError('Y U NO GIVE GOOD SIGNATURE') jws.algos.CUSTOM = [ ('F7U12', F7U12) ] header = {'alg': 'F7U12'} payload = {'some': 'claim'} sig = jws.sign(header, payload, 'wutlol') self.assertEqual(jws.verify(header,payload,sig, 'wutlol'), '<trollface>') self.assertRaises(jws.SignatureError, jws.verify, header, payload, sig, 'raaaaage')
def test_custom_algorithm(self): class F7U12(jws.algos.AlgorithmBase): def __init__(self): pass def sign(self, msg, key): return "u mad?" + key def verify(self, msg, sig, key): if sig == "u mad?" + key: return "<trollface>" raise jws.SignatureError("Y U NO GIVE GOOD SIGNATURE") jws.algos.CUSTOM = [("F7U12", F7U12)] header = {"alg": "F7U12"} payload = {"some": "claim"} sig = jws.sign(header, payload, "wutlol") self.assertEqual(jws.verify(header, payload, sig, "wutlol"), "<trollface>") self.assertRaises(jws.SignatureError, jws.verify, header, payload, sig, "raaaaage")
def verify_title_version(): try: signed_title = request.get_json() signature = signed_title['sig'] #signed_data is currently unicode. Incompatible with JWS. Convert to ASCII signature = signature.encode('ascii', 'ignore') title = json.dumps(signed_title['data']) # #import keys key = get_key() header = {'alg': 'RS256'} the_result = jws.verify(header, title, signature, key) except HTTPException as err: http_exception = '. HTTP exception occurred. ' app.logger.error(http_exception) app.logger.error(traceback.format_exc()) return http_exception, err.code except SignatureError as err: signature_error = '. Could not validate signature. ' app.logger.info(signature_error) return signature_error, 200 except MintUserException as err: app.logger.error(make_log_msg(str(err), request, ERROR_LOG_FILENAME, get_title_number(request))) app.logger.error(traceback.format_exc()) return str(err), 500 except Exception as err: unknown_error = '. unknown error in application.server.verify_title_version. ' app.logger.error(make_log_msg(unknown_error, request, ERROR_LOG_FILENAME, get_title_number(request))) app.logger.error(traceback.format_exc()) return unknown_error, 500 else: if the_result: app.logger.info( make_log_msg(". AUDIT: Verified signed title. ", request, INFO_LOG_FILENAME, get_title_number(request))) return "verified", 200
def verify_jwt(jwt, pub_key=None, iat_skew=timedelta(), checks_optional=False): """ Verify a JSON Web Token. :param jwt: The JSON Web Token to verify. :type jwt: str :param pub_key: The public key to be used to verify the token. Note: if you pass ``None`` then the token's signature will not be verified. :type pub_key: `_RSAobj <https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html>`_, `VerifyingKey <https://github.com/warner/python-ecdsa>`_, str or NoneType :param iat_skew: The amount of leeway to allow between the issuer's clock and the verifier's clock when verifiying that the token was generated in the past. Defaults to no leeway. :type iat_skew: datetime.timedelta :param checks_optional: Whether the token must contain the **typ** header property and the **iat**, **nbf** and **exp** claim properties. :type checks_optional: bool :rtype: tuple :returns: ``(header, claims)`` if the token was verified successfully. The token must pass the following tests: - Its signature must verify using the public key or its algorithm must be ``none``. - If the corresponding property is present or **checks_optional** is ``False``: - Its header must contain a property **typ** with the value ``JWT``. - Its claims must contain a property **iat** which represents a date in the past (taking into account :obj:`iat_skew`). - Its claims must contian a property **nbf** which represents a date in the past. - Its claims must contain a property **exp** which represents a date in the future. :raises: If the token failed to verify. """ header, claims, sig = jwt.split('.') header = jws.utils.from_base64(header) parsed_header = jws.utils.from_json(header) claims = jws.utils.from_base64(claims) if pub_key and parsed_header['alg'] != 'none': jws.verify(header, claims, sig, pub_key, True) header = parsed_header claims = jws.utils.from_json(claims) utcnow = datetime.utcnow() now = timegm(utcnow.utctimetuple()) typ = header.get('typ') if typ is None: if not checks_optional: raise _JWTError('type not present') elif typ != 'JWT': raise _JWTError('type is not JWT') iat = claims.get('iat') if iat is None: if not checks_optional: raise _JWTError('iat claim not present') elif iat > timegm((utcnow + iat_skew).utctimetuple()): raise _JWTError('issued in the future') nbf = claims.get('nbf') if nbf is None: if not checks_optional: raise _JWTError('nbf claim not present') elif nbf > now: raise _JWTError('not yet valid') exp = claims.get('exp') if exp is None: if not checks_optional: raise _JWTError('exp claim not present') elif exp <= now: raise _JWTError('expired') return header, claims
def test_valid_rsa384(self): header = {'alg': 'RS384'} sinput, sig = jws.sign(header, self.payload, self.private) public = self.private.publickey() self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, public))
def test_valid_hmac512(self): header = {'alg': 'HS512'} sinput, sig = jws.sign(header, self.payload, 'secret') self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, 'secret'))
def test_valid_rsa512_pss(self): header = {'alg': 'PS512'} sig = jws.sign(header, self.payload, self.private) public = self.private.publickey() self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, public))
def verify_jws_signature(state, task_meta, **options): try: data = task_meta['data'] node_id = task_meta['node_id'] key_node = get_node_by_path(state, [node_id, 'verification', 'creator']) public_pem = key_node['publicKeyPem'] except ( KeyError, IndexError, ): raise TaskPrerequisitesError() actions = [ add_task(VERIFY_KEY_OWNERSHIP, node_id=node_id), add_task(VALIDATE_PROPERTY, node_path=[node_id, 'badge', 'issuer'], prop_name='revocationList', prop_type=ValueTypes.ID, expected_class=OBClasses.RevocationList, fetch=True, required=False, prerequisites=[ISSUER_PROPERTY_DEPENDENCIES]), ] separator = '.' if sys.version[:3] > '3': separator = separator.encode('utf8') header, payload, signature = data.split(separator) if sys.version[:3] > '3': signature = make_string_from_bytes(signature) print("VERIFY JWS SIGNATURE : public_pem:") print(public_pem) print("VERIFY JWS SIGNATURE : signature:") print(signature) try: header_data = b64decode(header) if not isinstance(header_data, str): header_data = header_data.decode('utf-8') print("VERIFY JWS SIGNATURE : header_data:") print(header_data) payload_data = b64decode(payload) if not isinstance(payload_data, str): payload_data = payload_data.decode('utf-8') print("VERIFY JWS SIGNATURE : payload_data:") print(payload_data) except TypeError: return task_result( False, "Signature for node {} failed to unpack into a predictable format". format(node_id)) try: jws.verify(header_data, payload_data, signature, public_pem, is_json=True) except (jws.exceptions.SignatureError, TypeError) as e: return task_result( False, "Signature for node {} failed verification".format(node_id) + " :: " + str(e), actions) return task_result( True, "Signature for node {} passed verification".format(node_id), actions)
def test_valid_rsa384_pkcs1_5(self): header = {'alg': 'RS384'} sig = jws.sign(header, self.payload, self.private) public = self.private.publickey() self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, public))
def test_valid_ecdsa256(self): key = self.sk256 header = {"alg": "ES256"} sig = jws.sign(header, self.payload, key) self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, key.get_verifying_key()))
def test_valid_hmac512(self): header = {"alg": "HS512"} sig = jws.sign(header, self.payload, "secret") self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, "secret"))
def test_valid_rsa256(self): header = {"alg": "RS256"} sig = jws.sign(header, self.payload, self.private) public = self.private.publickey() self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, public))
def verify_jwt(jwt, pub_key=None, allowed_algs=None, iat_skew=timedelta(), checks_optional=False, ignore_not_implemented=False): """ Verify a JSON Web Token. :param jwt: The JSON Web Token to verify. :type jwt: str or unicode :param pub_key: The public key to be used to verify the token. Note: if you pass ``None`` and **allowed_algs** contains ``none`` then the token's signature will not be verified. :type pub_key: `_RSAobj <https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA._RSAobj-class.html>`_, `VerifyingKey <https://github.com/warner/python-ecdsa>`_, str or NoneType :param allowed_algs: Algorithms expected to be used to sign the token. The ``in`` operator is used to test membership. :type allowed_algs: list, dict or NoneType :param iat_skew: The amount of leeway to allow between the issuer's clock and the verifier's clock when verifiying that the token was generated in the past. Defaults to no leeway. :type iat_skew: datetime.timedelta :param checks_optional: If ``False``, then the token must contain the **typ** header property and the **iat**, **nbf** and **exp** claim properties. :type checks_optional: bool :param ignore_not_implemented: If ``False``, then the token must *not* contain the **jku**, **kid**, **x5u** or **x5t** header properties. :type ignore_not_implemented: bool :rtype: tuple :returns: ``(header, claims)`` if the token was verified successfully. The token must pass the following tests: - Its header must contain a property **alg** with a value in **allowed_algs**. - Its signature must verify using **pub_key** (unless its algorithm is ``none`` and ``none`` is in **allowed_algs**). - If the corresponding property is present or **checks_optional** is ``False``: - Its header must contain a property **typ** with the value ``JWT``. - Its claims must contain a property **iat** which represents a date in the past (taking into account :obj:`iat_skew`). - Its claims must contain a property **nbf** which represents a date in the past. - Its claims must contain a property **exp** which represents a date in the future. :raises: If the token failed to verify. """ header, claims, sig = jwt.split('.') header = jws.utils.from_base64(header).decode('utf-8') parsed_header = jws.utils.from_json(header) if allowed_algs is None: allowed_algs = [] alg = parsed_header.get('alg') if alg is None: raise _JWTError('alg not present') if alg not in allowed_algs: raise _JWTError('algorithm not allowed: ' + alg) claims = jws.utils.from_base64(claims).decode('utf-8') if pub_key: _tls.ignore_not_implemented = ignore_not_implemented try: jws.verify(header, claims, sig, pub_key, True) finally: _tls.ignore_not_implemented = False elif 'none' not in allowed_algs: raise _JWTError('no key but none alg not allowed') parsed_claims = jws.utils.from_json(claims) utcnow = datetime.utcnow() now = timegm(utcnow.utctimetuple()) typ = parsed_header.get('typ') if typ is None: if not checks_optional: raise _JWTError('type not present') elif typ != 'JWT': raise _JWTError('type is not JWT') iat = parsed_claims.get('iat') if iat is None: if not checks_optional: raise _JWTError('iat claim not present') elif iat > timegm((utcnow + iat_skew).utctimetuple()): raise _JWTError('issued in the future') nbf = parsed_claims.get('nbf') if nbf is None: if not checks_optional: raise _JWTError('nbf claim not present') elif nbf > now: raise _JWTError('not yet valid') exp = parsed_claims.get('exp') if exp is None: if not checks_optional: raise _JWTError('exp claim not present') elif exp <= now: raise _JWTError('expired') return parsed_header, parsed_claims
import jws header = {'alg': 'HS256'} payload = {'name': 'Kuntal Samanta', 'age': '25'} # Creating signature signature = jws.sign(header, payload, 'key') # Validating signature res = jws.verify(header, payload, signature, 'key') print(res)
def from_jwt(jwt, key): (header, claim, sig) = jwt.split('.') header = jws.utils.decode(header) claim = jws.utils.decode(claim) jws.verify(header, claim, sig, key) return claim
def test_valid_hmac512(self): header = {'alg': 'HS512'} sig = jws.sign(header, self.payload, 'secret') self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, 'secret'))
def test_valid_ecdsa512(self): key = self.sk512 header = {'alg': 'ES512'} sig = jws.sign(header, self.payload, key) self.assertTrue(len(sig) > 0) self.assertTrue(jws.verify(header, self.payload, sig, key.get_verifying_key()))