Esempio n. 1
0
    def test_attack_pubkey_deception_jwk(self):
        rsa256_token_header = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"
        rsa256_token_payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
        rsa256_token_signature = "ZR8EJ-ssd7b3Z9ZrCODkK_tJvOVXNZbcUn_FQAbLlKjPdEkNNCP_i5h84QfRXA8cWu1Z83UOb25Oogw0GIE9k-Q4AJO-BwEC2muHKRdzgHGrO6_2abeFJxAZapSf4ww39UlGzYX22b2kRYECLmsVaa0NV1KyQIf147h460wDGDr1wd2OCvUZXYULA_vzzRo3HHX440XOx_CnBvrR7shqnIjOLycEG61Ganq6oJsujVXHTQUtKdNB1Amu9NEQRRQzYWSTLuUMwV9mJnCuyr9bWp5srd3VPOC1bMXU2UgJiauw8eYu_w2_bbgZOn0jwajiygkfuJXNJGi8k_09sJmJ0w"
        rsa_token_ser = ".".join([
            rsa256_token_header, rsa256_token_payload, rsa256_token_signature
        ])
        rsa_token = TestJWT.deserialize(rsa_token_ser)
        self.assertEqual("RS256", rsa_token.get_algorithm())
        self.assertEqual("JWT", rsa_token.header['typ'])
        self.assertEqual(2, len(rsa_token.header))
        self.assertEqual("1234567890", rsa_token.payload['sub'])
        self.assertEqual("John Doe", rsa_token.payload['name'])
        self.assertEqual(1516239022, rsa_token.payload['iat'])
        self.assertEqual(3, len(rsa_token.payload))
        pk: RSAPrivateKey = load_pem_private_key(
            utils.read_pem_file("./keys/pk1.pem"), None, default_backend())
        pubkey: RSAPublicKey = pk.public_key()
        self.assertTrue(
            rsa_token.verify_signature(
                pubkey, utils.base64url_decode(rsa256_token_signature)))

        rsa_token_jwk = TestJWT.deserialize(rsa_token_ser)
        kid = "my_own_key"
        attack = Attack(rsa_token_ser)
        attack.attack_pubkey_deception_jwk(pk, kid)
        payloads = attack.payloads
        rsa_token_jwk = TestJWT.deserialize(
            payloads['attack_pubkey_deception_jwk'])
        self.assertEqual("RS256", rsa_token_jwk.get_algorithm())
        self.assertEqual("JWT", rsa_token_jwk.header['typ'])
        self.assertEqual("RSA", rsa_token_jwk.header['jwk']['kty'])
        self.assertEqual(kid, rsa_token_jwk.header['jwk']['kid'])
        self.assertEqual("sig", rsa_token_jwk.header['jwk']['use'])
        e = pk.public_key().public_numbers().e
        n = pk.public_key().public_numbers().n
        expected_n = utils.force_unicode(
            utils.base64url_encode(
                n.to_bytes((n.bit_length() + 7) // 8, byteorder='big')))
        expected_e = utils.force_unicode(
            utils.base64url_encode(
                e.to_bytes((e.bit_length() + 7) // 8, byteorder='big')))
        self.assertEqual(expected_n, rsa_token_jwk.header['jwk']['n'])
        self.assertEqual(expected_e, rsa_token_jwk.header['jwk']['e'])
        self.assertEqual(3, len(rsa_token_jwk.header))
        self.assertEqual("1234567890", rsa_token_jwk.payload['sub'])
        self.assertEqual("John Doe", rsa_token_jwk.payload['name'])
        self.assertEqual(1516239022, rsa_token_jwk.payload['iat'])
        self.assertEqual(3, len(rsa_token_jwk.payload))
        rsa_token_jwk_signature = rsa_token_jwk.compute_signature(pk)
        self.assertTrue(
            rsa_token_jwk.verify_signature(
                pubkey, utils.base64url_decode(rsa_token_jwk_signature)))
        expected_signature = "jheDPqm8kxisAUcuDX-gHdTEIQDan_qRphZddj2VkcW-wJbVARly1Wzaw4of96Dl0xJXqJBV_kKG5UmmEiiEjQWUZzY4_XuZmI_STEf7FvVe_OPbN6fmyzGJQZSJVaoXTMYw8_yhQ1fIip6ctGVKrt6752RolratwDsYVZawQ1J9V3WIioPvXjQoyEGbothy7yOxemZXB71SMcQ-mmLKc8v0mirA8kyR8Wg0lw_JkRVRbViItn6SMFg2_Fuf12P1rkxx2qo3BVPzvgz1Nln4U8kFe2HGdtpc2IMTrAvzO0hOhc8cBe2-9HZJAFdGd_6SPhkp1VVlx-qTIL2y0EqH4Q"
        self.assertEqual(expected_signature,
                         utils.force_unicode(rsa_token_jwk_signature))
Esempio n. 2
0
def encode(payload, key, algorithm='HS256'):
    segments = []
    header = {"typ": "JWT", "alg": algorithm}
    segments.append(base64url_encode(json.dumps(header)))
    segments.append(base64url_encode(json.dumps(payload)))
    signing_input = '.'.join(segments)
    try:
        signature = JWS(header, payload).sign(key)
    except KeyError:
        raise NotImplementedError("Algorithm not supported")
    segments.append(base64url_encode(signature))
    return '.'.join(segments)
Esempio n. 3
0
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
Esempio n. 4
0
 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
Esempio n. 5
0
 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 public_key_b64(self):
        """
        Convert the public key as base64 for sharing
        :return: Base64 Encoded Str()
        """
        public_numbers = self.public_key.public_numbers()

        return utils.base64url_encode('{x}{y}'.format(x=int2bytes(public_numbers.x),
                                                      y=int2bytes(public_numbers.y)))
Esempio n. 7
0
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')
Esempio n. 8
0
def make_jwt(claims, authorized_token):
    """
    Convert claims into JWT

    :type claims: Dictionary that will be converted to json
    :param claims: payload data
    :param authorized_token: Token to sign the request
    :return: JWT
    """
    alg = {'alg': 'ES256',
           'typ': 'JWT'}
    alg_serialized = json.dumps(alg)
    alg_b64 = utils.base64url_encode(alg_serialized)

    claims_serialized = json.dumps(claims)
    claims_b64 = utils.base64url_encode(claims_serialized)

    payload = '{alg}.{claims}'.format(alg=alg_b64, claims=claims_b64)

    signature = authorized_token.sign(payload)

    return '{payload}.{sig}'.format(payload=payload, sig=signature)
    def sign(self, payload):
        """
        Sign a payload
        :param payload: String (usually jwt payload)
        :return: URL safe base64 signature
        """
        signer = self._private_key.signer(ec.ECDSA(hashes.SHA256()))

        signer.update(payload)
        signature = signer.finalize()

        r, s = decode_dss_signature(signature)

        b64_signature = utils.base64url_encode('{r}{s}'.format(r=int2bytes(r),
                                                               s=int2bytes(s)))
        return b64_signature