Example #1
0
def make_valid_rsa_key(priv_key, pub_key):
    """Generate a valid private key, with N close to the N from pub_key"""

    # Attempt to make the key valid by finding a Q which multiplies with P to
    # form something close to N
    n = pub_key.public_numbers().n
    e = pub_key.public_numbers().e
    p = priv_key.private_numbers().p
    q = close_prime(n // p)

    assert is_prime(e)
    assert is_prime(p)
    assert is_prime(q)

    # Compute D from the new P&Q
    phi = (p - 1) * (q - 1)

    return rsa.RSAPrivateNumbers(
        public_numbers=rsa.RSAPublicNumbers(e, p * q),
        p=p,
        q=q,
        d=rsa.rsa_crt_iqmp(phi, e),
        dmp1=rsa.rsa_crt_dmp1(e, p),
        dmq1=rsa.rsa_crt_dmp1(e, q),
        iqmp=rsa.rsa_crt_iqmp(p, q),
    ).private_key(BACKEND)
Example #2
0
    def convert_key(cls, packet, private=False):
        if isinstance(packet, RSAPrivateKey) or isinstance(packet, RSAPublicKey) or isinstance(packet, DSAPublicKey) or isinstance(packet, DSAPrivateKey):
            if (not private) and (isinstance(packet, DSAPrivateKey) or isinstance(packet, RSAPrivateKey)):
                return packet.public_key()
            else:
                return packet

        packet = cls._parse_packet(packet)
        if isinstance(packet, OpenPGP.Message):
            packet = packet[0]

        if packet.key_algorithm_name() == 'DSA':
          params = dsa.DSAParameterNumbers(
                    cls._bytes_to_long(packet.key['p']),
                    cls._bytes_to_long(packet.key['q']),
                    cls._bytes_to_long(packet.key['g']))
          public = dsa.DSAPublicNumbers(
                    cls._bytes_to_long(packet.key['y']),
                    params)
          if private:
              return dsa.DSAPrivateNumbers(cls._bytes_to_long(packet.key['x']), public).private_key(openssl.backend)
          else:
              return public.public_key(openssl.backend)
        else: # RSA
          public = rsa.RSAPublicNumbers(cls._bytes_to_long(packet.key['e']), cls._bytes_to_long(packet.key['n']))
          if private:
              d = cls._bytes_to_long(packet.key['d'])
              p = cls._bytes_to_long(packet.key['q'])
              q = cls._bytes_to_long(packet.key['p'])
              dmp1 = rsa.rsa_crt_dmp1(d, p)
              dmq1 = rsa.rsa_crt_dmp1(d, q)
              u = cls._bytes_to_long(packet.key['u'])
              return rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, u, public).private_key(default_backend())
          else:
              return public.public_key(default_backend())
Example #3
0
    def fields_from_json(cls, jobj):
        # pylint: disable=invalid-name
        n, e = (cls._decode_param(jobj[x]) for x in ('n', 'e'))
        public_numbers = rsa.RSAPublicNumbers(e=e, n=n)
        if 'd' not in jobj:  # public key
            key = public_numbers.public_key(default_backend())
        else:  # private key
            d = cls._decode_param(jobj['d'])
            if ('p' in jobj or 'q' in jobj or 'dp' in jobj or
                    'dq' in jobj or 'qi' in jobj or 'oth' in jobj):
                # "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."
                p, q, dp, dq, qi, = all_params = tuple(
                    jobj.get(x) for x in ('p', 'q', 'dp', 'dq', 'qi'))
                if tuple(param for param in all_params if param is None):
                    raise errors.Error(
                        "Some private parameters are missing: {0}".format(
                            all_params))
                p, q, dp, dq, qi = tuple(cls._decode_param(x) for x in all_params)

                # TODO: check for oth
            else:
                p, q = rsa.rsa_recover_prime_factors(n, e, d)  # cryptography>=0.8
                dp = rsa.rsa_crt_dmp1(d, p)
                dq = rsa.rsa_crt_dmq1(d, q)
                qi = rsa.rsa_crt_iqmp(p, q)

            key = rsa.RSAPrivateNumbers(
                p, q, d, dp, dq, qi, public_numbers).private_key(default_backend())

        return cls(key=key)
Example #4
0
def generateKeyPair(keySize):
    p = generateLargePrime(keySize)
    print('Generating q prime...')
    q = generateLargePrime(keySize)
    n = p * q

    # Step 2: Create a number e that is relatively prime to (p-1)*(q-1).
    print('Generating e that is relatively prime to (p-1)*(q-1)...')
    while True:
        e = random.randrange(2 ** (keySize - 1), 2 ** (keySize))
        if gcd(e, (p - 1) * (q - 1)) == 1:
            break

    # Step 3: Calculate d, the mod inverse of e.
    print('Calculating d that is mod inverse of e...')
    d = findModInverse(e, (p - 1) * (q - 1))
    iqmp = rsa.rsa_crt_iqmp(p, q)
    dmp1 = rsa.rsa_crt_dmp1(d,p)
    dmq1 = rsa.rsa_crt_dmq1(d, q)
    public_key_numbers = rsa.RSAPublicNumbers(e,n)
    publicKey = public_key_numbers.public_key(default_backend());
    private_key_numbers = rsa.RSAPrivateNumbers(
        p,
        q,
        d,
        dmp1,
        dmq1,
        iqmp,
        public_key_numbers
    )
    privateKey = private_key_numbers.private_key(default_backend())
    print('Public key:', publicKey)
    print('Private key:', privateKey)
    return (publicKey, privateKey, str(p))
Example #5
0
    def compute_rsa_private_key(cls, p, q, e, n, d):
        """
        Computes RSA private key based on provided RSA semi-primes
            and returns cryptography lib instance.

        @developer: tnanoba

        :param p: int
        :param q: int
        :param e: int
        :param n: int
        :param d: int
        :return: object
        """

        # Computes: d % (p - 1)
        dmp1 = rsa.rsa_crt_dmp1(d, p)

        # Computes: d % (q - 1)
        dmq1 = rsa.rsa_crt_dmq1(d, q)

        # Modular inverse q of p, (q ^ -1 mod p)
        iqmp = rsa.rsa_crt_iqmp(p, q)

        public_numbers = rsa.RSAPublicNumbers(e, n)

        return rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp,
                                     public_numbers).private_key(
                                         default_backend())
Example #6
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)
Example #7
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')
Example #8
0
def _deserialize_rsa_private_key(stream: typing.BinaryIO) -> rsa.RSAPrivateKey:
    rsa_n = _sshbuf_get_bignum2(stream)
    rsa_e = _sshbuf_get_bignum2(stream)
    rsa_d = _sshbuf_get_bignum2(stream)
    rsa_iqmp = _sshbuf_get_bignum2(stream)
    rsa_p = _sshbuf_get_bignum2(stream)
    rsa_q = _sshbuf_get_bignum2(stream)

    # Calculate Chinese remainder theorem coefficients
    # used to speed up calculations.
    # Luckily, our library provides functions to calculate these...

    rsa_dmp1 = rsa.rsa_crt_dmp1(rsa_d, rsa_p)  # dmp1 = d mod (p - 1)
    rsa_dmq1 = rsa.rsa_crt_dmq1(rsa_d, rsa_q)  # dmp2 = d mod (q - 1)

    public_numbers = rsa.RSAPublicNumbers(e=rsa_e, n=rsa_n)
    private_numbers = rsa.RSAPrivateNumbers(
        p=rsa_p,
        q=rsa_q,
        d=rsa_d,
        dmp1=rsa_dmp1,
        dmq1=rsa_dmq1,
        iqmp=rsa_iqmp,
        public_numbers=public_numbers,
    )
    return private_numbers.private_key(backend=default_backend())
Example #9
0
def convert_to_pem(jwks_keys):
    pem_keys = []
    for jwk_key in jwks_keys:
        e = jwk_key.get('e')
        n = jwk_key.get('n')
        d = jwk_key.get('d')

        # We don't have p, q, dp, dq and qi but you can recover it with knowledge of d
        # if you have p and q you wouldn't need the d but could calculate d from this.

        (p, q) = rsa.rsa_recover_prime_factors(n, e, d)

        dp = rsa.rsa_crt_dmp1(d, p)
        dq = rsa.rsa_crt_dmq1(d, q)
        qi = rsa.rsa_crt_iqmp(p, q)

        public_numbers = rsa.RSAPublicNumbers(e=e, n=n)

        key = rsa.RSAPrivateNumbers(
            p, q, d, dp, dq, qi, public_numbers).private_key(default_backend())
        pem_string = key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption())

        pem_keys.append(pem_string.decode('ascii'))

    return pem_keys
Example #10
0
def build_rsa_private(n,
                      public,
                      private,
                      p=-1,
                      q=-1,
                      dmp1=-1,
                      dmq1=-1,
                      iqmp=-1):
    """A wrapper function to create an RSA private key from given parameters.

    Keyword arguments:
    n -- the modulus
    public -- the public exponent
    private -- the private exponent
    p -- (optional) prime 1
    q -- (optional) prime 2
    dmp1 -- (optional) CRT exponent 1
    dmq1 -- (optional) CRT exponent 2
    iqmp --- (optional) CRT coefficient
    """
    if p == -1 or q == -1:
        p, q = rsa.recover_prime_factors(n, public, private)
    if dmp1 == -1:
        dmp1 = rsa.rsa_crt_dmp1(private, p)
    if dmq1 == -1:
        dmq1 = rsa.rsa_crt_dmq1(private, q)
    if iqmp == -1:
        iqmp = rsa.rsa_crt_iqmp(p, q)
    pubNum = rsa.RSAPublicNumbers(public, n)
    privNum = rsa.RSAPrivateNumbers(p, q, private, dmp1, dmq1, iqmp, pubNum)
    return default_backend().load_rsa_private_numbers(privNum)
Example #11
0
    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())
Example #12
0
def load_jwks(jwks_obj):
    """
    Given a JWKS-formatted dictionary representing a private key,
    return a python-cryptography private key object
    """

    if jwks_obj['kty'] == "RSA":
        n = long_from_bytes(jwks_obj['n'])
        e = long_from_bytes(jwks_obj['e'])
        d = long_from_bytes(jwks_obj['d'])
        public_key_numbers = rsa.RSAPublicNumbers(
            e = e,
            n = n,
        )
        # If loading a partial key, we'll have to recalculate a
        # few of the relevant constants
        if ('p' not in jwks_obj) or ('q' not in jwks_obj):
            p, q = rsa.rsa_recover_prime_factors(n, e, d)
        else:
            p = long_from_bytes(jwks_obj['p'])
            q = long_from_bytes(jwks_obj['q'])
        if 'qi' not in jwks_obj:
            qi = rsa.rsa_crt_iqmp(p, q)
        else:
            qi = long_from_bytes(jwks_obj['qi'])
        if 'dp' not in jwks_obj:
            dmp1 = rsa.rsa_crt_dmp1(d, p)
        else:
            dmp1 = long_from_bytes(jwks_obj['dp'])
        if 'dq' not in jwks_obj:
            dmq1 = rsa.rsa_crt_dmq1(d, q)
        else:
            dmq1 = long_from_bytes(jwks_obj['dq'])
        private_key_numbers = rsa.RSAPrivateNumbers(
            p = p,
            q = q,
            d = d,
            dmp1 = dmp1,
            dmq1 = dmq1,
            iqmp = qi,
            public_numbers = public_key_numbers
        )
        return private_key_numbers.private_key(default_backend())
    elif jwks_obj['kty'] == 'EC':
        public_key_numbers = ec.EllipticCurvePublicNumbers(
            long_from_bytes(jwks_obj['x']),
            long_from_bytes(jwks_obj['y']),
            ec.SECP256R1()
        )
        private_key_numbers = ec.EllipticCurvePrivateNumbers(
            long_from_bytes(jwks_obj['d']),
            public_key_numbers
        )
        return private_key_numbers.private_key(default_backend())
    else:
        raise scitokens.scitokens.UnsupportedKeyException("Issuer public key not supported.")
Example #13
0
    def __init__(
        self,
        n: str,
        e: str,
        d: Optional[str] = None,
        p: Optional[str] = None,
        q: Optional[str] = None,
        dp: Optional[str] = None,
        dq: Optional[str] = None,
        qi: Optional[str] = None,
        **ignore,
    ) -> None:
        self._private = None
        self._public = None

        modulus = b64_to_int(n)
        public_exponent = b64_to_int(e)

        public = rsa.RSAPublicNumbers(public_exponent, modulus)
        self._public: RSA_PUBLIC = public.public_key(default_backend())

        if d:
            private_exponent = b64_to_int(d)
            first_prime = b64_to_int(p)
            second_prime = b64_to_int(q)
            first_prime_crt = b64_to_int(dp)
            second_prime_crt = b64_to_int(dq)
            crt_coefficient = b64_to_int(qi)

            if not first_prime or not second_prime:
                first_prime, second_prime = rsa.rsa_recover_prime_factors(
                    modulus, public_exponent, private_exponent)

            if not first_prime_crt:
                first_prime_crt = rsa.rsa_crt_dmp1(private_exponent,
                                                   first_prime)

            if not second_prime_crt:
                second_prime_crt = rsa.rsa_crt_dmq1(private_exponent,
                                                    second_prime)

            if not crt_coefficient:
                crt_coefficient = rsa.rsa_crt_iqmp(first_prime, second_prime)

            private = rsa.RSAPrivateNumbers(
                first_prime,
                second_prime,
                private_exponent,
                first_prime_crt,
                second_prime_crt,
                crt_coefficient,
                public,
            )

            self._private: RSA_PRIVATE = private.private_key(default_backend())
Example #14
0
def _check_rsa_private_numbers(skey):
    assert skey
    pkey = skey.public_numbers
    assert pkey
    assert pkey.e
    assert pkey.n
    assert skey.d
    assert skey.p * skey.q == pkey.n
    assert skey.dmp1 == rsa.rsa_crt_dmp1(skey.d, skey.p)
    assert skey.dmq1 == rsa.rsa_crt_dmq1(skey.d, skey.q)
    assert skey.iqmp == rsa.rsa_crt_iqmp(skey.p, skey.q)
Example #15
0
def make_privkey(p, q, e=65537):
    n = p * q
    d = number.inverse(e, (p - 1) * (q - 1))
    iqmp = rsa.rsa_crt_iqmp(p, q)
    dmp1 = rsa.rsa_crt_dmp1(e, p)
    dmq1 = rsa.rsa_crt_dmq1(e, q)
    pub = rsa.RSAPublicNumbers(e, n)
    priv = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pub)
    pubkey = pub.public_key(default_backend())
    privkey = priv.private_key(default_backend())
    return privkey, pubkey
Example #16
0
    def __init__(self, p: int, n: int, e: int, pubnums: rsa.RSAPublicNumbers):

        q = n // p

        d = _MyRSAPrivateNumbers._generate_d(p, q, e, n)

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

        super().__init__(p, q, d, dmp1, dmq1, iqmp, pubnums)
Example #17
0
def _check_rsa_private_numbers(skey):
    assert skey
    pkey = skey.public_numbers
    assert pkey
    assert pkey.e
    assert pkey.n
    assert skey.d
    assert skey.p * skey.q == pkey.n
    assert skey.dmp1 == rsa.rsa_crt_dmp1(skey.d, skey.p)
    assert skey.dmq1 == rsa.rsa_crt_dmq1(skey.d, skey.q)
    assert skey.iqmp == rsa.rsa_crt_iqmp(skey.p, skey.q)
Example #18
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
Example #19
0
    def convert_key(cls, packet, private=False):
        if (
            isinstance(packet, RSAPrivateKey)
            or isinstance(packet, RSAPublicKey)
            or isinstance(packet, DSAPublicKey)
            or isinstance(packet, DSAPrivateKey)
        ):
            if (not private) and (isinstance(packet, DSAPrivateKey) or isinstance(packet, RSAPrivateKey)):
                return packet.public_key()
            else:
                return packet

        packet = cls._parse_packet(packet)
        if isinstance(packet, OpenPGP.Message):
            packet = packet[0]

        if packet.key_algorithm_name() == "DSA":
            params = dsa.DSAParameterNumbers(
                cls._bytes_to_long(packet.key["p"]),
                cls._bytes_to_long(packet.key["q"]),
                cls._bytes_to_long(packet.key["g"]),
            )
            public = dsa.DSAPublicNumbers(cls._bytes_to_long(packet.key["y"]), params)
            if private:
                return dsa.DSAPrivateNumbers(cls._bytes_to_long(packet.key["x"]), public).private_key(openssl.backend)
            else:
                return public.public_key(openssl.backend)
        else:  # RSA
            public = rsa.RSAPublicNumbers(cls._bytes_to_long(packet.key["e"]), cls._bytes_to_long(packet.key["n"]))
            if private:
                d = cls._bytes_to_long(packet.key["d"])
                p = cls._bytes_to_long(packet.key["q"])
                q = cls._bytes_to_long(packet.key["p"])
                dmp1 = rsa.rsa_crt_dmp1(d, p)
                dmq1 = rsa.rsa_crt_dmp1(d, q)
                u = cls._bytes_to_long(packet.key["u"])
                return rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, u, public).private_key(default_backend())
            else:
                return public.public_key(default_backend())
Example #20
0
def rsa_construct_private(numbers):
    args = dict([(k, v) for k, v in numbers.items() if k in ["n", "e", "d"]])
    cnum = {"d": numbers["d"]}
    if "p" not in numbers and "q" not in numbers:
        (p, q) = rsa.rsa_recover_prime_factors(**args)
        cnum["p"] = p
        cnum["q"] = q
    else:
        cnum["p"] = numbers["p"]
        cnum["q"] = numbers["q"]

    try:
        cnum["dmp1"] = numbers["dp"]
    except KeyError:
        cnum["dmp1"] = rsa.rsa_crt_dmp1(cnum["d"], cnum["p"])
    else:
        if not numbers["dp"]:
            cnum["dmp1"] = rsa.rsa_crt_dmp1(cnum["d"], cnum["p"])

    try:
        cnum["dmq1"] = numbers["dq"]
    except KeyError:
        cnum["dmq1"] = rsa.rsa_crt_dmq1(cnum["d"], cnum["q"])
    else:
        if not numbers["dq"]:
            cnum["dmq1"] = rsa.rsa_crt_dmq1(cnum["d"], cnum["q"])

    try:
        cnum["iqmp"] = numbers["di"]
    except KeyError:
        cnum["iqmp"] = rsa.rsa_crt_iqmp(cnum["p"], cnum["q"])
    else:
        if not numbers["di"]:
            cnum["iqmp"] = rsa.rsa_crt_iqmp(cnum["p"], cnum["q"])

    rpubn = rsa.RSAPublicNumbers(e=numbers["e"], n=numbers["n"])
    rprivn = rsa.RSAPrivateNumbers(public_numbers=rpubn, **cnum)
    return rprivn.private_key(default_backend())
Example #21
0
def rsa_construct_private(numbers):
    args = dict([(k, v) for k, v in numbers.items() if k in ['n', 'e', 'd']])
    cnum = {'d': numbers['d']}
    if 'p' not in numbers and 'q' not in numbers:
        (p, q) = rsa.rsa_recover_prime_factors(**args)
        cnum['p'] = p
        cnum['q'] = q
    else:
        cnum['p'] = numbers['p']
        cnum['q'] = numbers['q']

    try:
        cnum['dmp1'] = numbers['dp']
    except KeyError:
        cnum['dmp1'] = rsa.rsa_crt_dmp1(cnum['d'], cnum['p'])
    else:
        if not numbers['dp']:
            cnum['dmp1'] = rsa.rsa_crt_dmp1(cnum['d'], cnum['p'])

    try:
        cnum['dmq1'] = numbers['dq']
    except KeyError:
        cnum['dmq1'] = rsa.rsa_crt_dmq1(cnum['d'], cnum['q'])
    else:
        if not numbers['dq']:
            cnum['dmq1'] = rsa.rsa_crt_dmq1(cnum['d'], cnum['q'])

    try:
        cnum['iqmp'] = numbers['di']
    except KeyError:
        cnum['iqmp'] = rsa.rsa_crt_iqmp(cnum['p'], cnum['p'])
    else:
        if not numbers['di']:
            cnum['iqmp'] = rsa.rsa_crt_iqmp(cnum['p'], cnum['p'])

    rpubn = rsa.RSAPublicNumbers(e=numbers['e'], n=numbers['n'])
    rprivn = rsa.RSAPrivateNumbers(public_numbers=rpubn, **cnum)
    return rprivn.private_key(default_backend())
Example #22
0
    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())
Example #23
0
def make_rsa_privkey(material, backend):
    public_material = material['public']
    private_material = material['private']
    n = public_material['n']  # Note: all the number are already int
    e = public_material['e']
    d = private_material['d']
    p = private_material['p']
    q = private_material['q']
    pub = rsa.RSAPublicNumbers(e, n)
    dmp1 = rsa.rsa_crt_dmp1(d, p)
    dmq1 = rsa.rsa_crt_dmq1(d, q)
    iqmp = rsa.rsa_crt_iqmp(p, q)
    return rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp,
                                 pub).private_key(backend)
Example #24
0
def rsa_pq(p, q, e=65537):
    n = p * q
    public_numbers = rsa.RSAPublicNumbers(e=e, n=n)
    d = rsa._modinv(e, (p - 1) * (q - 1) // 2)
    private_numbers = rsa.RSAPrivateNumbers(
        public_numbers=public_numbers,
        p=p,
        q=q,
        d=d,
        dmp1=rsa.rsa_crt_dmp1(d, p),
        dmq1=rsa.rsa_crt_dmq1(d, q),
        iqmp=rsa.rsa_crt_iqmp(p, q),
    )
    return private_numbers.private_key(backend)
Example #25
0
    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())
Example #26
0
def make_rsa_key(material):
    '''Convert a hex-based dict of values to an RSA key'''
    backend = default_backend()
    public_material = material['public']
    private_material = material['private']
    n = int(public_material['n'], 16)
    e = int(public_material['e'], 16)
    d = int(private_material['d'], 16)
    p = int(private_material['p'], 16)
    q = int(private_material['q'], 16)
    pub = rsa.RSAPublicNumbers(e, n)
    dmp1 = rsa.rsa_crt_dmp1(d, p)
    dmq1 = rsa.rsa_crt_dmq1(d, q)
    iqmp = rsa.rsa_crt_iqmp(p, q)
    return rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp,
                                 pub).private_key(backend), padding.PKCS1v15()
Example #27
0
def _check_rsa_private_key(skey):
    assert skey
    assert skey.modulus
    assert skey.public_exponent
    assert skey.private_exponent
    assert skey.p * skey.q == skey.modulus
    assert skey.key_size
    assert skey.dmp1 == rsa.rsa_crt_dmp1(skey.d, skey.p)
    assert skey.dmq1 == rsa.rsa_crt_dmq1(skey.d, skey.q)
    assert skey.iqmp == rsa.rsa_crt_iqmp(skey.p, skey.q)

    pkey = skey.public_key()
    assert pkey
    assert skey.modulus == pkey.modulus
    assert skey.public_exponent == pkey.public_exponent
    assert skey.key_size == pkey.key_size
def print_sign_test(case, n, e, d, padding_alg):
    # Recover the prime factors and CRT numbers.
    p, q = rsa.rsa_recover_prime_factors(n, e, d)
    # cryptography returns p, q with p < q by default. *ring* requires
    # p > q, so swap them here.
    p, q = max(p, q), min(p, q)
    dmp1 = rsa.rsa_crt_dmp1(d, p)
    dmq1 = rsa.rsa_crt_dmq1(d, q)
    iqmp = rsa.rsa_crt_iqmp(p, q)

    # Create a private key instance.
    pub = rsa.RSAPublicNumbers(e, n)

    priv = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pub)
    key = priv.private_key(default_backend())

    msg = case['Msg'].decode('hex')

    # Recalculate and compare the signature to validate our processing.
    if padding_alg == 'PKCS#1 1.5':
        sig = key.sign(msg, padding.PKCS1v15(),
                       getattr(hashes, case['SHAAlg'])())
        hex_sig = to_hex(sig)
        assert hex_sig == case['S']
    elif padding_alg == "PSS":
        # PSS is randomised, can't recompute this way
        pass
    else:
        print "Invalid padding algorithm"
        quit()

    # Serialize the private key in DER format.
    der = key.private_bytes(serialization.Encoding.DER,
                            serialization.PrivateFormat.TraditionalOpenSSL,
                            serialization.NoEncryption())

    # Print the test case data in the format used by *ring* test files.
    print 'Digest = %s' % case['SHAAlg']
    print 'Key = %s' % to_hex(der)
    print 'Msg = %s' % reformat_hex(case['Msg'])

    if padding_alg == "PSS":
        print 'Salt = %s' % reformat_hex(case['SaltVal'])

    print 'Sig = %s' % reformat_hex(case['S'])
    print 'Result = Pass'
    print ''
Example #29
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
Example #30
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')
        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)
def main(fn):
    for case in parse(fn):

        if case['SHAAlg'] == 'SHA224':
            # SHA224 not supported in *ring*.
            continue

        # Read private key components.
        n = int(case['n'], 16)
        e = int(case['e'], 16)
        d = int(case['d'], 16)

        # Recover the prime factors and CRT numbers.
        p, q = rsa.rsa_recover_prime_factors(n, e, d)
        # cryptography returns p, q with p < q by default. *ring* requires
        # p > q, so swap them here.
        p, q = max(p, q), min(p, q)
        dmp1 = rsa.rsa_crt_dmp1(d, p)
        dmq1 = rsa.rsa_crt_dmq1(d, q)
        iqmp = rsa.rsa_crt_iqmp(p, q)

        # Create a private key instance.
        pub = rsa.RSAPublicNumbers(e, n)
        priv = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pub)
        key = priv.private_key(default_backend())

        # Recalculate and compare the signature to validate our processing.
        msg = case['Msg'].decode('hex')
        sig = key.sign(msg, padding.PKCS1v15(),
                       getattr(hashes, case['SHAAlg'])())
        hex_sig = ''.join('{:02x}'.format(ord(c)) for c in sig)
        assert hex_sig == case['S']

        # Serialize the private key in DER format.
        der = key.private_bytes(serialization.Encoding.DER,
                                serialization.PrivateFormat.TraditionalOpenSSL,
                                serialization.NoEncryption())
        hex_der = ''.join('{:02x}'.format(ord(c)) for c in der)

        # Print the test case data in the format used by *ring* test files.
        print 'Digest = %s' % case['SHAAlg']
        print 'Key = %s' % hex_der
        print 'Msg = %s' % case['Msg']
        print 'Sig = %s' % case['S']
        print 'Result = Pass'
        print ''
Example #32
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)
Example #33
0
    def load_private(self, data, pubfields, backend):
        """Make RSA private key from data."""
        n, data = _get_mpint(data)
        e, data = _get_mpint(data)
        d, data = _get_mpint(data)
        iqmp, data = _get_mpint(data)
        p, data = _get_mpint(data)
        q, data = _get_mpint(data)

        if (e, n) != pubfields:
            raise ValueError("Corrupt data: rsa field mismatch")
        dmp1 = rsa.rsa_crt_dmp1(d, p)
        dmq1 = rsa.rsa_crt_dmq1(d, q)
        public_numbers = rsa.RSAPublicNumbers(e, n)
        private_numbers = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp,
                                                public_numbers)
        private_key = private_numbers.private_key(backend)
        return private_key, data
Example #34
0
    def _load_prikey_with_decrypted_data(self, decrypted_prikey_data):
        der_pri = der_decoder.decode(decrypted_prikey_data)
        der_pri2 = der_decoder.decode(der_pri[0][2])

        # (n, e, d, p, q)
        (n, e, d, p, q) = (der_pri2[0][1], der_pri2[0][2], der_pri2[0][3], der_pri2[0][4], der_pri2[0][5])
        (n, e, d, p, q) = (int(n), int(e), int(d), int(p), int(q))
        iqmp = rsa_crt_iqmp(p, q)
        dmp1 = rsa_crt_dmp1(e, p)
        dmq1 = rsa_crt_dmq1(e, q)
        pn = RSAPublicNumbers(n=n, e=e)

        self.prikey = RSAPrivateNumbers(p=p, q=q, d=d, dmp1=dmp1, dmq1=dmq1, iqmp=iqmp,
                                        public_numbers=pn).private_key(backend=default_backend())
        if len(der_pri[0]) > 3:
            # sometimes, r value is not exist -  (i don't know why..)
            self._rand_num = der_pri[0][3][1][0]  # so raw data, can't be eaten
        return
Example #35
0
    def _fromRSAComponents(cls, n, e, d=None, p=None, q=None, u=None):
        """
        Build a key from RSA numerical components.

        @type n: L{int}
        @param n: The 'n' RSA variable.

        @type e: L{int}
        @param e: The 'e' RSA variable.

        @type d: L{int} or C{None}
        @param d: The 'd' RSA variable (optional for a public key).

        @type p: L{int} or C{None}
        @param p: The 'p' RSA variable (optional for a public key).

        @type q: L{int} or C{None}
        @param q: The 'q' RSA variable (optional for a public key).

        @type u: L{int} or C{None}
        @param u: The 'u' RSA variable. Ignored, as its value is determined by
        p and q.

        @rtype: L{Key}
        @return: An RSA key constructed from the values as given.
        """
        publicNumbers = rsa.RSAPublicNumbers(e=e, n=n)
        if d is None:
            # We have public components.
            keyObject = publicNumbers.public_key(default_backend())
        else:
            privateNumbers = rsa.RSAPrivateNumbers(
                p=p,
                q=q,
                d=d,
                dmp1=rsa.rsa_crt_dmp1(d, p),
                dmq1=rsa.rsa_crt_dmq1(d, q),
                iqmp=rsa.rsa_crt_iqmp(p, q),
                public_numbers=publicNumbers,
                )
            keyObject = privateNumbers.private_key(default_backend())

        return cls(keyObject)
Example #36
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError(
                "Incorrect key type.  Expected: 'RSA', Received: %s" %
                jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))
        public = rsa.RSAPublicNumbers(e, n)

        if 'd' not in jwk_dict:
            return public.public_key(self.cryptography_backend())
        else:
            # This is a private key.
            d = base64_to_long(jwk_dict.get('d'))

            extra_params = ['p', 'q', 'dp', 'dq', 'qi']

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError(
                        'Precomputed private key parameters are incomplete.')

                p = base64_to_long(jwk_dict['p'])
                q = base64_to_long(jwk_dict['q'])
                dp = base64_to_long(jwk_dict['dp'])
                dq = base64_to_long(jwk_dict['dq'])
                qi = base64_to_long(jwk_dict['qi'])
            else:
                # The precomputed private key parameters are not available,
                # so we use cryptography's API to fill them in.
                p, q = rsa.rsa_recover_prime_factors(n, e, d)
                dp = rsa.rsa_crt_dmp1(d, p)
                dq = rsa.rsa_crt_dmq1(d, q)
                qi = rsa.rsa_crt_iqmp(p, q)

            private = rsa.RSAPrivateNumbers(p, q, d, dp, dq, qi, public)

            return private.private_key(self.cryptography_backend())
Example #37
0
def create_privete_key(public_key, q):
    n = public_key.public_numbers().n
    e = public_key.public_numbers().e
    p = n // q

    phi = (p - 1) * (q - 1)
    d = egcd(e, phi)
    d = d % phi

    if d < 0:
        d += phi

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

    private_key = rsa.RSAPrivateNumbers(
        p, q, d, dmp1, dmq1, iqmp, public_key.public_numbers()).private_key()
    return private_key
Example #38
0
    def _fromRSAComponents(cls, n, e, d=None, p=None, q=None, u=None):
        """
        Build a key from RSA numerical components.

        @type n: L{int}
        @param n: The 'n' RSA variable.

        @type e: L{int}
        @param e: The 'e' RSA variable.

        @type d: L{int} or L{None}
        @param d: The 'd' RSA variable (optional for a public key).

        @type p: L{int} or L{None}
        @param p: The 'p' RSA variable (optional for a public key).

        @type q: L{int} or L{None}
        @param q: The 'q' RSA variable (optional for a public key).

        @type u: L{int} or L{None}
        @param u: The 'u' RSA variable. Ignored, as its value is determined by
        p and q.

        @rtype: L{Key}
        @return: An RSA key constructed from the values as given.
        """
        publicNumbers = rsa.RSAPublicNumbers(e=e, n=n)
        if d is None:
            # We have public components.
            keyObject = publicNumbers.public_key(default_backend())
        else:
            privateNumbers = rsa.RSAPrivateNumbers(
                p=p,
                q=q,
                d=d,
                dmp1=rsa.rsa_crt_dmp1(d, p),
                dmq1=rsa.rsa_crt_dmq1(d, q),
                iqmp=rsa.rsa_crt_iqmp(p, q),
                public_numbers=publicNumbers,
            )
            keyObject = privateNumbers.private_key(default_backend())

        return cls(keyObject)
Example #39
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
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError("Incorrect key type.  Expected: 'RSA', Received: %s" % jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))
        public = rsa.RSAPublicNumbers(e, n)

        if 'd' not in jwk_dict:
            return public.public_key(self.cryptography_backend())
        else:
            # This is a private key.
            d = base64_to_long(jwk_dict.get('d'))

            extra_params = ['p', 'q', 'dp', 'dq', 'qi']

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError('Precomputed private key parameters are incomplete.')

                p = base64_to_long(jwk_dict['p'])
                q = base64_to_long(jwk_dict['q'])
                dp = base64_to_long(jwk_dict['dp'])
                dq = base64_to_long(jwk_dict['dq'])
                qi = base64_to_long(jwk_dict['qi'])
            else:
                # The precomputed private key parameters are not available,
                # so we use cryptography's API to fill them in.
                p, q = rsa.rsa_recover_prime_factors(n, e, d)
                dp = rsa.rsa_crt_dmp1(d, p)
                dq = rsa.rsa_crt_dmq1(d, q)
                qi = rsa.rsa_crt_iqmp(p, q)

            private = rsa.RSAPrivateNumbers(p, q, d, dp, dq, qi, public)

            return private.private_key(self.cryptography_backend())
Example #41
0
 def __privkey__(self):
     return rsa.RSAPrivateNumbers(self.p, self.q, self.d,
                                  rsa.rsa_crt_dmp1(self.d, self.p),
                                  rsa.rsa_crt_dmq1(self.d, self.q),
                                  rsa.rsa_crt_iqmp(self.p, self.q),
                                  rsa.RSAPublicNumbers(self.e, self.n)).private_key(default_backend())
Example #42
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')