コード例 #1
0
        def from_jwk(jwk):
            try:
                obj = json.loads(jwk)
            except ValueError:
                raise InvalidKeyError('Key is not valid JSON')

            if obj.get != 'RSA':
                raise InvalidKeyError('Not an RSA key')

            if 'd' in obj and 'e' in obj and 'n' in obj:
                # Private key
                if 'oth' in obj:
                    raise InvalidKeyError(
                        'Unsupported RSA private key: > 2 primes not supported'
                    )

                other_props = ['p', 'q', 'dp', 'dq', 'qi']
                props_found = [prop in obj for prop in other_props]
                any_props_found = any(props_found)

                if any_props_found and not all(props_found):
                    raise InvalidKeyError(
                        'RSA key must include all parameters if any are present besides d'
                    )

                public_numbers = RSAPublicNumbers(
                    from_base64url_uint(obj['e']),
                    from_base64url_uint(obj['n']))

                if any_props_found:
                    numbers = RSAPrivateNumbers(
                        d=from_base64url_uint(obj['d']),
                        p=from_base64url_uint(obj['p']),
                        q=from_base64url_uint(obj['q']),
                        dmp1=from_base64url_uint(obj['dp']),
                        dmq1=from_base64url_uint(obj['dq']),
                        iqmp=from_base64url_uint(obj['qi']),
                        public_numbers=public_numbers)
                else:
                    d = from_base64url_uint(obj['d'])
                    p, q = rsa_recover_prime_factors(public_numbers.n, d,
                                                     public_numbers.e)

                    numbers = RSAPrivateNumbers(d=d,
                                                p=p,
                                                q=q,
                                                dmp1=rsa_crt_dmp1(d, p),
                                                dmq1=rsa_crt_dmq1(d, q),
                                                iqmp=rsa_crt_iqmp(p, q),
                                                public_numbers=public_numbers)

                return numbers.private_key(default_backend())
            elif 'n' in obj and 'e' in obj:
                # Public key
                numbers = RSAPublicNumbers(from_base64url_uint(obj['e']),
                                           from_base64url_uint(obj['n']))

                return numbers.public_key(default_backend())
            else:
                raise InvalidKeyError('Not a public or private key')
コード例 #2
0
ファイル: rsa_key.py プロジェクト: imfht/flaskapps
    def load_private_key(self):
        obj = self._dict_data

        if 'oth' in obj:  # pragma: no cover
            # https://tools.ietf.org/html/rfc7518#section-6.3.2.7
            raise ValueError('"oth" is not supported yet')

        public_numbers = RSAPublicNumbers(base64_to_int(obj['e']),
                                          base64_to_int(obj['n']))

        if has_all_prime_factors(obj):
            numbers = RSAPrivateNumbers(d=base64_to_int(obj['d']),
                                        p=base64_to_int(obj['p']),
                                        q=base64_to_int(obj['q']),
                                        dmp1=base64_to_int(obj['dp']),
                                        dmq1=base64_to_int(obj['dq']),
                                        iqmp=base64_to_int(obj['qi']),
                                        public_numbers=public_numbers)
        else:
            d = base64_to_int(obj['d'])
            p, q = rsa_recover_prime_factors(public_numbers.n, d,
                                             public_numbers.e)
            numbers = RSAPrivateNumbers(d=d,
                                        p=p,
                                        q=q,
                                        dmp1=rsa_crt_dmp1(d, p),
                                        dmq1=rsa_crt_dmq1(d, q),
                                        iqmp=rsa_crt_iqmp(p, q),
                                        public_numbers=public_numbers)

        return numbers.private_key(default_backend())
コード例 #3
0
def _convert_rsa_private_key(keypair):
    backend = Backend()

    def _trim_bn_to_int(s):
        binary = s.lstrip(b'\x00')
        bn_ptr = backend._lib.BN_bin2bn(binary, len(binary), backend._ffi.NULL)
        try:
            return backend._bn_to_int(bn_ptr)
        finally:
            backend._lib.OPENSSL_free(bn_ptr)

    (n, e, d, iqmp, p, q) = [
        _trim_bn_to_int(value)
        for value in _read_KEY_RSA(io.BytesIO(keypair.private_key))
    ]

    numbers = RSAPrivateNumbers(
        d=d,
        p=p,
        q=q,
        dmp1=rsa_crt_dmp1(d, p),
        dmq1=rsa_crt_dmq1(d, q),
        iqmp=rsa_crt_iqmp(p, q),
        public_numbers=RSAPublicNumbers(e=e, n=n),
    )

    return numbers.private_key(backend)
コード例 #4
0
ファイル: _internal.py プロジェクト: jaysterp/azure-cli
    def from_jwk(jwk):
        if not isinstance(jwk, JsonWebKey):
            raise TypeError('The specified jwk must be a JsonWebKey')

        if jwk.kty != 'RSA' and jwk.kty != 'RSA-HSM':
            raise ValueError(
                'The specified jwk must have a key type of "RSA" or "RSA-HSM"')

        if not jwk.n or not jwk.e:
            raise ValueError(
                'Invalid RSA jwk, both n and e must be have values')

        rsa_key = _RsaKey()
        rsa_key.kid = jwk.kid
        rsa_key.kty = jwk.kty
        rsa_key.key_ops = jwk.key_ops

        pub = RSAPublicNumbers(n=_bytes_to_int(jwk.n), e=_bytes_to_int(jwk.e))

        # if the private key values are specified construct a private key
        # only the secret primes and private exponent are needed as other fields can be calculated
        if jwk.p and jwk.q and jwk.d:
            # convert the values of p, q, and d from bytes to int
            p = _bytes_to_int(jwk.p)
            q = _bytes_to_int(jwk.q)
            d = _bytes_to_int(jwk.d)

            # convert or compute the remaining private key numbers
            dmp1 = _bytes_to_int(jwk.dp) if jwk.dp else rsa_crt_dmp1(
                private_exponent=d, p=p)
            dmq1 = _bytes_to_int(jwk.dq) if jwk.dq else rsa_crt_dmq1(
                private_exponent=d, q=q)
            iqmp = _bytes_to_int(jwk.qi) if jwk.qi else rsa_crt_iqmp(p=p, q=q)

            # create the private key from the jwk key values
            priv = RSAPrivateNumbers(p=p,
                                     q=q,
                                     d=d,
                                     dmp1=dmp1,
                                     dmq1=dmq1,
                                     iqmp=iqmp,
                                     public_numbers=pub)
            key_impl = priv.private_key(
                cryptography.hazmat.backends.default_backend())

        # if the necessary private key values are not specified create the public key
        else:
            key_impl = pub.public_key(
                cryptography.hazmat.backends.default_backend())

        rsa_key._rsa_impl = key_impl

        return rsa_key
コード例 #5
0
ファイル: rsa.py プロジェクト: nchammas/asyncssh
    def __init__(self, n, e, d, p, q):
        self.n = n
        self.e = e
        self.d = d
        self.p = p
        self.q = q

        dmp1 = rsa_crt_dmp1(d, p)
        dmq1 = rsa_crt_dmq1(d, q)
        iqmp = rsa_crt_iqmp(p, q)

        pub = RSAPublicNumbers(e, n)
        priv = RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pub)
        self._key = priv.private_key(default_backend())
コード例 #6
0
ファイル: rsa.py プロジェクト: marksandhu/asyncssh
    def __init__(self, n, e, d, p, q):
        self.n = n
        self.e = e
        self.d = d
        self.p = p
        self.q = q

        dmp1 = rsa_crt_dmp1(d, p)
        dmq1 = rsa_crt_dmq1(d, q)
        iqmp = rsa_crt_iqmp(p, q)

        pub = RSAPublicNumbers(e, n)
        priv = RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pub)
        self._key = priv.private_key(default_backend())
コード例 #7
0
    def from_jwk(cls, jwk):
        if jwk.kty != "RSA" and jwk.kty != "RSA-HSM":
            raise ValueError(
                'The specified jwk must have a key type of "RSA" or "RSA-HSM"')

        if not jwk.n or not jwk.e:
            raise ValueError(
                "Invalid RSA jwk, both n and e must be have values")

        rsa_key = cls(kid=jwk.kid)
        rsa_key.kty = jwk.kty
        rsa_key.key_ops = jwk.key_ops

        pub = RSAPublicNumbers(n=_bytes_to_int(jwk.n), e=_bytes_to_int(jwk.e))

        # if the private key values are specified construct a private key
        # only the secret primes and private exponent are needed as other fields can be calculated
        if jwk.p and jwk.q and jwk.d:
            # convert the values of p, q, and d from bytes to int
            p = _bytes_to_int(jwk.p)
            q = _bytes_to_int(jwk.q)
            d = _bytes_to_int(jwk.d)

            # convert or compute the remaining private key numbers
            dmp1 = _bytes_to_int(jwk.dp) if jwk.dp else rsa_crt_dmp1(
                private_exponent=d, p=p)
            dmq1 = _bytes_to_int(jwk.dq) if jwk.dq else rsa_crt_dmq1(
                private_exponent=d, q=q)
            iqmp = _bytes_to_int(jwk.qi) if jwk.qi else rsa_crt_iqmp(p=p, q=q)

            # create the private key from the jwk key values
            priv = RSAPrivateNumbers(p=p,
                                     q=q,
                                     d=d,
                                     dmp1=dmp1,
                                     dmq1=dmq1,
                                     iqmp=iqmp,
                                     public_numbers=pub)
            key_impl = priv.private_key(default_backend())

        # if the necessary private key values are not specified create the public key
        else:
            key_impl = pub.public_key(default_backend())

        rsa_key._rsa_impl = key_impl  # pylint:disable=protected-access

        return rsa_key
コード例 #8
0
ファイル: jwk.py プロジェクト: GehirnInc/python-jwt
    def from_dict(cls, dct):
        if 'oth' in dct:
            raise UnsupportedKeyTypeError(
                'RSA keys with multiples primes are not supported')

        try:
            e = uint_b64decode(dct['e'])
            n = uint_b64decode(dct['n'])
        except KeyError as why:
            raise MalformedJWKError('e and n are required')
        pub_numbers = RSAPublicNumbers(e, n)
        if 'd' not in dct:
            return cls(
                pub_numbers.public_key(backend=default_backend()), **dct)
        d = uint_b64decode(dct['d'])

        privparams = {'p', 'q', 'dp', 'dq', 'qi'}
        product = set(dct.keys()) & privparams
        if len(product) == 0:
            p, q = rsa_recover_prime_factors(n, e, d)
            priv_numbers = RSAPrivateNumbers(
                d=d,
                p=p,
                q=q,
                dmp1=rsa_crt_dmp1(d, p),
                dmq1=rsa_crt_dmq1(d, q),
                iqmp=rsa_crt_iqmp(p, q),
                public_numbers=pub_numbers)
        elif product == privparams:
            priv_numbers = RSAPrivateNumbers(
                d=d,
                p=uint_b64decode(dct['p']),
                q=uint_b64decode(dct['q']),
                dmp1=uint_b64decode(dct['dp']),
                dmq1=uint_b64decode(dct['dq']),
                iqmp=uint_b64decode(dct['qi']),
                public_numbers=pub_numbers)
        else:
            # If the producer includes any of the other private key parameters,
            # then all of the others MUST be present, with the exception of
            # "oth", which MUST only be present when more than two prime
            # factors were used.
            raise MalformedJWKError(
                'p, q, dp, dq, qi MUST be present or'
                'all of them MUST be absent')
        return cls(priv_numbers.private_key(backend=default_backend()), **dct)
コード例 #9
0
    def from_dict(cls, dct):
        if 'oth' in dct:
            raise UnsupportedKeyTypeError(
                'RSA keys with multiples primes are not supported')

        try:
            e = uint_b64decode(dct['e'])
            n = uint_b64decode(dct['n'])
        except KeyError as why:
            raise MalformedJWKError('e and n are required') from why
        pub_numbers = RSAPublicNumbers(e, n)
        if 'd' not in dct:
            return cls(
                pub_numbers.public_key(backend=default_backend()), **dct)
        d = uint_b64decode(dct['d'])

        privparams = {'p', 'q', 'dp', 'dq', 'qi'}
        product = set(dct.keys()) & privparams
        if len(product) == 0:
            p, q = rsa_recover_prime_factors(n, e, d)
            priv_numbers = RSAPrivateNumbers(
                d=d,
                p=p,
                q=q,
                dmp1=rsa_crt_dmp1(d, p),
                dmq1=rsa_crt_dmq1(d, q),
                iqmp=rsa_crt_iqmp(p, q),
                public_numbers=pub_numbers)
        elif product == privparams:
            priv_numbers = RSAPrivateNumbers(
                d=d,
                p=uint_b64decode(dct['p']),
                q=uint_b64decode(dct['q']),
                dmp1=uint_b64decode(dct['dp']),
                dmq1=uint_b64decode(dct['dq']),
                iqmp=uint_b64decode(dct['qi']),
                public_numbers=pub_numbers)
        else:
            # If the producer includes any of the other private key parameters,
            # then all of the others MUST be present, with the exception of
            # "oth", which MUST only be present when more than two prime
            # factors were used.
            raise MalformedJWKError(
                'p, q, dp, dq, qi MUST be present or'
                'all of them MUST be absent')
        return cls(priv_numbers.private_key(backend=default_backend()), **dct)
コード例 #10
0
    def loads_private_key(self, obj):
        if 'oth' in obj:
            # https://tools.ietf.org/html/rfc7518#section-6.3.2.7
            return self.loads_other_primes_info(obj)

        props = ['p', 'q', 'dp', 'dq', 'qi']
        props_found = [prop in obj for prop in props]
        any_props_found = any(props_found)

        if any_props_found and not all(props_found):
            raise ValueError('RSA key must include all parameters if any are present besides d')

        public_numbers = RSAPublicNumbers(
            base64_to_int(obj['e']), base64_to_int(obj['n'])
        )

        if any_props_found:
            numbers = RSAPrivateNumbers(
                d=base64_to_int(obj['d']),
                p=base64_to_int(obj['p']),
                q=base64_to_int(obj['q']),
                dmp1=base64_to_int(obj['dp']),
                dmq1=base64_to_int(obj['dq']),
                iqmp=base64_to_int(obj['qi']),
                public_numbers=public_numbers
            )
        else:
            d = base64_to_int(obj['d'])
            p, q = rsa_recover_prime_factors(
                public_numbers.n, d, public_numbers.e
            )
            numbers = RSAPrivateNumbers(
                d=d,
                p=p,
                q=q,
                dmp1=rsa_crt_dmp1(d, p),
                dmq1=rsa_crt_dmq1(d, q),
                iqmp=rsa_crt_iqmp(p, q),
                public_numbers=public_numbers
            )

        return numbers.private_key(default_backend())
コード例 #11
0
    def from_jwk(jwk):
        if not isinstance(jwk, JsonWebKey):
            raise TypeError('The specified jwk must be a JsonWebKey')

        if jwk.kty != 'RSA' and jwk.kty != 'RSA-HSM':
            raise ValueError('The specified jwk must have a key type of "RSA" or "RSA-HSM"')

        if not jwk.n or not jwk.e:
            raise ValueError('Invalid RSA jwk, both n and e must be have values')

        rsa_key = _RsaKey()
        rsa_key.kid = jwk.kid
        rsa_key.kty = jwk.kty
        rsa_key.key_ops = jwk.key_ops

        pub = RSAPublicNumbers(n=_bytes_to_int(jwk.n), e=_bytes_to_int(jwk.e))

        # if the private key values are specified construct a private key
        # only the secret primes and private exponent are needed as other fields can be calculated
        if jwk.p and jwk.q and jwk.d:
            # convert the values of p, q, and d from bytes to int
            p = _bytes_to_int(jwk.p)
            q = _bytes_to_int(jwk.q)
            d = _bytes_to_int(jwk.d)

            # convert or compute the remaining private key numbers
            dmp1 = _bytes_to_int(jwk.dp) if jwk.dp else rsa_crt_dmp1(private_exponent=d, p=p)
            dmq1 = _bytes_to_int(jwk.dq) if jwk.dq else rsa_crt_dmq1(private_exponent=d, q=q)
            iqmp = _bytes_to_int(jwk.qi) if jwk.qi else rsa_crt_iqmp(p=p, q=q)

            # create the private key from the jwk key values
            priv = RSAPrivateNumbers(p=p, q=q, d=d, dmp1=dmp1, dmq1=dmq1, iqmp=iqmp, public_numbers=pub)
            key_impl = priv.private_key(cryptography.hazmat.backends.default_backend())

        # if the necessary private key values are not specified create the public key
        else:
            key_impl = pub.public_key(cryptography.hazmat.backends.default_backend())

        rsa_key._rsa_impl = key_impl

        return rsa_key
コード例 #12
0
        def from_jwk(jwk):
            try:
                obj = json.loads(jwk)
            except ValueError:
                raise InvalidKeyError("Key is not valid JSON")

            if obj.get("kty") != "RSA":
                raise InvalidKeyError("Not an RSA key")

            if "d" in obj and "e" in obj and "n" in obj:
                # Private key
                if "oth" in obj:
                    raise InvalidKeyError(
                        "Unsupported RSA private key: > 2 primes not supported"
                    )

                other_props = ["p", "q", "dp", "dq", "qi"]
                props_found = [prop in obj for prop in other_props]
                any_props_found = any(props_found)

                if any_props_found and not all(props_found):
                    raise InvalidKeyError(
                        "RSA key must include all parameters if any are present besides d"
                    )

                public_numbers = RSAPublicNumbers(
                    from_base64url_uint(obj["e"]),
                    from_base64url_uint(obj["n"]),
                )

                if any_props_found:
                    numbers = RSAPrivateNumbers(
                        d=from_base64url_uint(obj["d"]),
                        p=from_base64url_uint(obj["p"]),
                        q=from_base64url_uint(obj["q"]),
                        dmp1=from_base64url_uint(obj["dp"]),
                        dmq1=from_base64url_uint(obj["dq"]),
                        iqmp=from_base64url_uint(obj["qi"]),
                        public_numbers=public_numbers,
                    )
                else:
                    d = from_base64url_uint(obj["d"])
                    p, q = rsa_recover_prime_factors(public_numbers.n, d,
                                                     public_numbers.e)

                    numbers = RSAPrivateNumbers(
                        d=d,
                        p=p,
                        q=q,
                        dmp1=rsa_crt_dmp1(d, p),
                        dmq1=rsa_crt_dmq1(d, q),
                        iqmp=rsa_crt_iqmp(p, q),
                        public_numbers=public_numbers,
                    )

                return numbers.private_key(default_backend())
            elif "n" in obj and "e" in obj:
                # Public key
                numbers = RSAPublicNumbers(
                    from_base64url_uint(obj["e"]),
                    from_base64url_uint(obj["n"]),
                )

                return numbers.public_key(default_backend())
            else:
                raise InvalidKeyError("Not a public or private key")
コード例 #13
0
    def __init__(self, params: Dict[int, Any]):
        super().__init__(params)

        self._key: Any = None
        self._hash: Any = None
        self._padding: Any = None
        salt_len: Any = padding.PSS.MAX_LENGTH

        # Validate kty.
        if params[1] != 3:
            raise ValueError("kty(1) should be RSA(3).")

        # Validate alg.
        if 3 not in params:
            raise ValueError("alg(3) not found.")
        if params[3] not in COSE_ALGORITHMS_RSA.values():
            raise ValueError(
                f"Unsupported or unknown alg(3) for RSA: {params[3]}.")
        if params[3] == -259 or params[3] == -39:
            self._hash = hashes.SHA512
            salt_len = 64
        elif params[3] == -258 or params[3] == -38:
            self._hash = hashes.SHA384
            salt_len = 48
        elif params[3] == -257 or params[3] == -37:
            self._hash = hashes.SHA256
            salt_len = 32
        else:
            raise ValueError(
                f"Unsupported or unknown alg(3) for RSA: {params[3]}.")
        if params[3] in [-37, -38, -39]:
            self._padding = padding.PSS(mgf=padding.MGF1(self._hash()),
                                        salt_length=salt_len)
        else:
            self._padding = padding.PKCS1v15()

        # Validate key_ops.
        if -3 not in params:  # the RSA private exponent d.
            if not self._key_ops:
                self._key_ops = RSAKey._ACCEPTABLE_PUBLIC_KEY_OPS
            else:
                prohibited = [
                    ops for ops in self._key_ops
                    if ops not in RSAKey._ACCEPTABLE_PUBLIC_KEY_OPS
                ]
                if prohibited:
                    raise ValueError(
                        f"Unknown or not permissible key_ops(4) for RSAKey: {prohibited[0]}."
                    )
        else:
            if not self._key_ops:
                self._key_ops = RSAKey._ACCEPTABLE_PRIVATE_KEY_OPS
            else:
                prohibited = [
                    ops for ops in self._key_ops
                    if ops not in RSAKey._ACCEPTABLE_PRIVATE_KEY_OPS
                ]
                if prohibited:
                    raise ValueError(
                        f"Unknown or not permissible key_ops(4) for RSAKey: {prohibited[0]}."
                    )

        # Validate RSA specific parameters.
        if -1 not in params or not isinstance(params[-1], bytes):
            raise ValueError("n(-1) should be set as bytes.")
        if -2 not in params or not isinstance(params[-2], bytes):
            raise ValueError("e(-2) should be set as bytes.")

        public_numbers = RSAPublicNumbers(
            n=int.from_bytes(params[-1], "big"),
            e=int.from_bytes(params[-2], "big"),
        )
        self._dict = params
        if -3 not in params:  # the RSA private exponent d.
            private_props = [
                p for p in params.keys() if p in [-4, -5, -6, -7, -8]
            ]
            if private_props:
                raise ValueError(
                    f"RSA public key should not have private parameter: {private_props[0]}."
                )
            self._key = public_numbers.public_key()
            return

        if -3 not in params or not isinstance(params[-3], bytes):
            raise ValueError("d(-3) should be set as bytes.")
        if -4 not in params or not isinstance(params[-4], bytes):
            raise ValueError("p(-4) should be set as bytes.")
        if -5 not in params or not isinstance(params[-5], bytes):
            raise ValueError("q(-5) should be set as bytes.")
        if -6 not in params or not isinstance(params[-6], bytes):
            raise ValueError("dP(-6) should be set as bytes.")
        if -7 not in params or not isinstance(params[-7], bytes):
            raise ValueError("dQ(-7) should be set as bytes.")
        if -8 not in params or not isinstance(params[-8], bytes):
            raise ValueError("qInv(-8) should be set as bytes.")

        private_numbers = RSAPrivateNumbers(
            d=int.from_bytes(params[-3], "big"),
            p=int.from_bytes(params[-4], "big"),
            q=int.from_bytes(params[-5], "big"),
            dmp1=int.from_bytes(params[-6], "big"),
            dmq1=int.from_bytes(params[-7], "big"),
            iqmp=int.from_bytes(params[-8], "big"),
            public_numbers=public_numbers,
        )
        self._key = private_numbers.private_key()
        return
コード例 #14
0
ファイル: algorithms.py プロジェクト: Zelgadis87/SickRage
        def from_jwk(jwk):
            try:
                obj = json.loads(jwk)
            except ValueError:
                raise InvalidKeyError('Key is not valid JSON')

            if obj.get('kty') != 'RSA':
                raise InvalidKeyError('Not an RSA key')

            if 'd' in obj and 'e' in obj and 'n' in obj:
                # Private key
                if 'oth' in obj:
                    raise InvalidKeyError('Unsupported RSA private key: > 2 primes not supported')

                other_props = ['p', 'q', 'dp', 'dq', 'qi']
                props_found = [prop in obj for prop in other_props]
                any_props_found = any(props_found)

                if any_props_found and not all(props_found):
                    raise InvalidKeyError('RSA key must include all parameters if any are present besides d')

                public_numbers = RSAPublicNumbers(
                    from_base64url_uint(obj['e']), from_base64url_uint(obj['n'])
                )

                if any_props_found:
                    numbers = RSAPrivateNumbers(
                        d=from_base64url_uint(obj['d']),
                        p=from_base64url_uint(obj['p']),
                        q=from_base64url_uint(obj['q']),
                        dmp1=from_base64url_uint(obj['dp']),
                        dmq1=from_base64url_uint(obj['dq']),
                        iqmp=from_base64url_uint(obj['qi']),
                        public_numbers=public_numbers
                    )
                else:
                    d = from_base64url_uint(obj['d'])
                    p, q = rsa_recover_prime_factors(
                        public_numbers.n, d, public_numbers.e
                    )

                    numbers = RSAPrivateNumbers(
                        d=d,
                        p=p,
                        q=q,
                        dmp1=rsa_crt_dmp1(d, p),
                        dmq1=rsa_crt_dmq1(d, q),
                        iqmp=rsa_crt_iqmp(p, q),
                        public_numbers=public_numbers
                    )

                return numbers.private_key(default_backend())
            elif 'n' in obj and 'e' in obj:
                # Public key
                numbers = RSAPublicNumbers(
                    from_base64url_uint(obj['e']), from_base64url_uint(obj['n'])
                )

                return numbers.public_key(default_backend())
            else:
                raise InvalidKeyError('Not a public or private key')