def urlencode(self, safe=None): """ Returns an encoded string of all query string arguments. :arg safe: Used to specify characters which do not require quoting, for example:: >>> q = QueryDict('', mutable=True) >>> q['next'] = '/a&b/' >>> q.urlencode() 'next=%2Fa%26b%2F' >>> q.urlencode(safe='/') 'next=/a%26b/' """ output = [] if safe: safe = force_bytes(safe, self.encoding) encode = lambda k, v: '%s=%s' % ((quote(k, safe), quote(v, safe))) else: encode = lambda k, v: urlencode({k: v}) for k, list_ in self.lists(): k = force_bytes(k, self.encoding) output.extend( encode(k, force_bytes(v, self.encoding)) for v in list_) return '&'.join(output)
def sign(alg, contents, key=None): print('Computing signature for alg {}'.format(alg)) # TODO move compute signature None here from attack_none if key is not None and isinstance(key, str): key = utils.force_bytes(key) if contents is not None: contents = utils.force_bytes(contents) if alg.lower() == 'none': return b'' if alg == "HS256": return utils.base64url_encode( hmac.new(key, contents, hashlib.sha256).digest()) if alg == "HS384": return utils.base64url_encode( hmac.new(key, contents, hashlib.sha384).digest()) if alg == "HS512": return utils.base64url_encode( hmac.new(key, contents, hashlib.sha512).digest()) if alg == "RS256": rsa_pk: RSAPrivateKey = key return utils.base64url_encode( rsa_pk.sign(data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA256())) if alg == "RS384": rsa_pk: RSAPrivateKey = key return utils.base64url_encode( rsa_pk.sign(contents, padding.PKCS1v15(), hashes.SHA384())) if alg == "RS512": rsa_pk: RSAPrivateKey = key return utils.base64url_encode( rsa_pk.sign(contents, padding.PKCS1v15(), hashes.SHA512())) return utils.force_bytes('N/A')
def build_section(dict_section): """ Builds a JWT section (header or payload) by properly encoding content. :param dict_section: JSON (dict) or plain text (str) content to be encoded :return: JWT encoded section """ if utils.is_dict(dict_section): new_section = utils.base64url_encode( utils.force_bytes( json.dumps(dict_section, separators=(",", ":")))) else: new_section = utils.base64url_encode( utils.force_bytes(dict_section)) return new_section
def compute_signature(self, key): alg = self.get_algorithm() print("Computing signature using alg {}".format(alg)) if alg is None: print("Signature algorithm not set") return False if str.capitalize(alg) == "NONE": return self.build_token_without_signature() # TODO reuse build_section content_to_sign = utils.base64url_encode( utils.force_bytes(json.dumps(self.header, separators=( ",", ":")))) + utils.force_bytes(".") + utils.base64url_encode( utils.force_bytes( json.dumps(self.payload, separators=(",", ":")))) return signatures.sign(alg, content_to_sign, key=key)
def verify_signature(self, key, expected_sig): alg = self.header['alg'] print("Verify signature using alg {}".format(alg)) if alg is None: print("Signature algorithm not set") return False if str.capitalize(alg) == "NONE": return True alg = self.get_algorithm() return signatures.verify(alg, self.build_token_without_signature(), key, utils.force_bytes(expected_sig))
def verify(alg, contents, key, sig): if key is not None and isinstance(key, str): key = utils.force_bytes(key) test_sig = "" if alg == "HS256": test_sig = utils.base64url_encode( hmac.new(key, contents, hashlib.sha256).digest()) elif alg == "HS384": test_sig = utils.base64url_encode( hmac.new(key, contents, hashlib.sha384).digest()) elif alg == "HS512": test_sig = utils.base64url_encode( hmac.new(key, contents, hashlib.sha512).digest()) elif alg == "RS256": rsa_pk: RSAPublicKey = key rsa_pk.verify(signature=sig, data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA256()) return True elif alg == "RS384": rsa_pk: RSAPublicKey = key rsa_pk.verify(signature=sig, data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA384()) return True elif alg == "RS512": rsa_pk: RSAPublicKey = key rsa_pk.verify(signature=sig, data=contents, padding=padding.PKCS1v15(), algorithm=hashes.SHA512()) return True else: print("Unknown algorithm {}".format(alg)) verified = False if test_sig == sig: verified = True if len(key) > 16: print("Signature verified using key {}...".format(key[0:16])) else: print("Signature verified using key {}...".format(key)) else: if len(key) > 16: print("WARN Signature verification fail using key {}...".format( key[0:16])) else: print( "WARN Signature verification fail using key {}...".format(key)) return verified
def build_token(self, key=None): content_to_sign = self.build_token_without_signature() return content_to_sign + utils.force_bytes('.') + signatures.sign( self.get_algorithm(), content_to_sign, key=key)
def build_token_without_signature(self): return TestJWT.build_section( self.header) + utils.force_bytes('.') + TestJWT.build_section( self.get_payload())
def test_hs256_signature(self): test_sig = self.tjwt.compute_signature(self.secret) self.assertEqual(utils.force_bytes(self.sig), test_sig)
def __repr__(self): return force_bytes("<%s: %s>" % (self.__class__.__name__, self or "None"))
def __repr__(self): return force_bytes( "<%s: %s (%s)>" % (self.__class__.__name__, self.name, self.content_type))