Example #1
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 #2
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 #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 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 #5
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 #6
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())
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 ''
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 #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')
        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 #10
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 #11
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 #12
0
    def get_private_key(n, e, d):
        '''
        Get private key object given private key numbers
            @in: key_numbers={'n':n, 'e':e,'d':d,}
            @out: private_key object
        '''
        # reconstruct private key
        p, q = rsa.rsa_recover_prime_factors(n, e, d)
        iqmp = rsa.rsa_crt_iqmp(p, q)
        dmp1 = rsa.rsa_crt_dmp1(d, p)
        dmq1 = rsa.rsa_crt_dmq1(d, q)

        # call RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, public_numbers)
        private_numbers = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp,
                                                rsa.RSAPublicNumbers(e, n))
        # get private key object
        private_key = private_numbers.private_key(default_backend())

        return private_key
Example #13
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())
    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 #15
0
    def fields_from_json(cls, jobj: Mapping[str, Any]) -> 'JWKRSA':
        # pylint: disable=invalid-name
        n, e = (cls._decode_param(jobj[x]) for x in ('n', 'e'))
        public_numbers = rsa.RSAPublicNumbers(e=e, n=n)

        # public key
        if 'd' not in jobj:
            return cls(key=public_numbers.public_key(default_backend()))

        # 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(str(x)) for x in all_params)

            # TODO: check for oth
        else:
            # cryptography>=0.8
            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)

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

        return cls(key=key)
Example #16
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 #17
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 #18
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')
Example #19
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")
        for ln in f:
            if not ln.strip():
                continue
            if ln[0] in {'#', '['}:
                continue
            name, val = ln.split('=', 1)
            cur[name.strip()] = val.strip()
            if name.strip() == last_field:
                cases.append(cur)
                cur = copy.copy(cur)
    return cases


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')
Example #21
0
def rsa_factor_given_private_key(n, e, d):
    return rsa.rsa_recover_prime_factors(n, e, d)