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