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)
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 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 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)
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 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())
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))
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 _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)
def data(self): """ Return the values of the public key as a dictionary. @rtype: L{dict} """ if isinstance(self._keyObject, rsa.RSAPublicKey): numbers = self._keyObject.public_numbers() return { "n": numbers.n, "e": numbers.e, } elif isinstance(self._keyObject, rsa.RSAPrivateKey): numbers = self._keyObject.private_numbers() return { "n": numbers.public_numbers.n, "e": numbers.public_numbers.e, "d": numbers.d, "p": numbers.p, "q": numbers.q, # Use a trick: iqmp is q^-1 % p, u is p^-1 % q "u": rsa.rsa_crt_iqmp(numbers.q, numbers.p), } elif isinstance(self._keyObject, dsa.DSAPublicKey): numbers = self._keyObject.public_numbers() return { "y": numbers.y, "g": numbers.parameter_numbers.g, "p": numbers.parameter_numbers.p, "q": numbers.parameter_numbers.q, } elif isinstance(self._keyObject, dsa.DSAPrivateKey): numbers = self._keyObject.private_numbers() return { "x": numbers.x, "y": numbers.public_numbers.y, "g": numbers.public_numbers.parameter_numbers.g, "p": numbers.public_numbers.parameter_numbers.p, "q": numbers.public_numbers.parameter_numbers.q, } elif isinstance(self._keyObject, ec.EllipticCurvePublicKey): numbers = self._keyObject.public_numbers() return { "x": numbers.x, "y": numbers.y, "curve": self.sshType(), } elif isinstance(self._keyObject, ec.EllipticCurvePrivateKey): numbers = self._keyObject.private_numbers() return { "x": numbers.public_numbers.x, "y": numbers.public_numbers.y, "privateValue": numbers.private_value, "curve": self.sshType(), } else: raise RuntimeError("Unexpected key type: %s" % (self._keyObject,))
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 _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)
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
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)
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 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 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)
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())
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)
def serialize(self, name, comment, email): rsa_priv = RSAPriv() rsa_priv.e = MPI(self.public_numbers._e) rsa_priv.n = MPI(self.public_numbers._n) rsa_priv.d = MPI(self._d) rsa_priv.p = MPI(self._p) rsa_priv.q = MPI(self._q) # https://github.com/SecurityInnovation/PGPy/blob/f08afed730816e71eafa0dd59ce77d8859ce24b5/pgpy/packet/fields.py#L1116 rsa_priv.u = MPI(rsa.rsa_crt_iqmp(self._q, self._p)) rsa_priv._compute_chksum() pub_key_v4 = PrivKeyV4() pub_key_v4.pkalg = PubKeyAlgorithm.RSAEncryptOrSign pub_key_v4.keymaterial = rsa_priv pub_key_v4.update_hlen() pgp_key = pgpy.PGPKey() pgp_key._key = pub_key_v4 uid = pgpy.PGPUID.new(name, comment=comment, email=email) # FIXME: Should I add a "Signature" Packet? # FIXME: Should I add subkeys? pgp_key.add_uid(uid, usage={ KeyFlags.Sign, KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage }, hashes=[ HashAlgorithm.SHA256, HashAlgorithm.SHA384, HashAlgorithm.SHA512, HashAlgorithm.SHA224 ], ciphers=[ SymmetricKeyAlgorithm.AES256, SymmetricKeyAlgorithm.AES192, SymmetricKeyAlgorithm.AES128 ], compression=[ CompressionAlgorithm.ZLIB, CompressionAlgorithm.BZ2, CompressionAlgorithm.ZIP, CompressionAlgorithm.Uncompressed ]) if self.password: pgp_key.protect(self.password, SymmetricKeyAlgorithm.AES256, HashAlgorithm.SHA256) return str(pgp_key)
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()
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 test_privateBlobRSA(self): """ L{keys.Key.privateBlob} returns the SSH protocol-level format of an RSA private key. """ from cryptography.hazmat.primitives.asymmetric import rsa numbers = self.rsaObj.private_numbers() u = rsa.rsa_crt_iqmp(numbers.q, numbers.p) self.assertEqual( keys.Key(self.rsaObj).privateBlob(), common.NS(b'ssh-rsa') + common.MP(self.rsaObj.private_numbers().public_numbers.n) + common.MP(self.rsaObj.private_numbers().public_numbers.e) + common.MP(self.rsaObj.private_numbers().d) + common.MP(u) + common.MP(self.rsaObj.private_numbers().p) + common.MP(self.rsaObj.private_numbers().q))
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 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
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 ''
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 _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
def test_privateBlobRSA(self): """ L{keys.Key.privateBlob} returns the SSH protocol-level format of an RSA private key. """ from cryptography.hazmat.primitives.asymmetric import rsa numbers = self.rsaObj.private_numbers() u = rsa.rsa_crt_iqmp(numbers.q, numbers.p) self.assertEqual( keys.Key(self.rsaObj).privateBlob(), common.NS(b'ssh-rsa') + common.MP(self.rsaObj.private_numbers().public_numbers.n) + common.MP(self.rsaObj.private_numbers().public_numbers.e) + common.MP(self.rsaObj.private_numbers().d) + common.MP(u) + common.MP(self.rsaObj.private_numbers().p) + common.MP(self.rsaObj.private_numbers().q) )
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 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
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)
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)
def data(self): """ Return the values of the public key as a dictionary. @rtype: C{dict} """ if isinstance(self._keyObject, rsa.RSAPublicKey): numbers = self._keyObject.public_numbers() return { "n": numbers.n, "e": numbers.e, } elif isinstance(self._keyObject, rsa.RSAPrivateKey): numbers = self._keyObject.private_numbers() return { "n": numbers.public_numbers.n, "e": numbers.public_numbers.e, "d": numbers.d, "p": numbers.p, "q": numbers.q, # Use a trick: iqmp is q^-1 % p, u is p^-1 % q "u": rsa.rsa_crt_iqmp(numbers.q, numbers.p), } elif isinstance(self._keyObject, dsa.DSAPublicKey): numbers = self._keyObject.public_numbers() return { "y": numbers.y, "g": numbers.parameter_numbers.g, "p": numbers.parameter_numbers.p, "q": numbers.parameter_numbers.q, } elif isinstance(self._keyObject, dsa.DSAPrivateKey): numbers = self._keyObject.private_numbers() return { "x": numbers.x, "y": numbers.public_numbers.y, "g": numbers.public_numbers.parameter_numbers.g, "p": numbers.public_numbers.parameter_numbers.p, "q": numbers.public_numbers.parameter_numbers.q, } else: raise RuntimeError("Unexpected key type: %s" % (self._keyObject,))
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())
def _generate(self, key_size): if any(c != 0 for c in self): # pragma: no cover raise PGPError("key is already populated") # generate some big numbers! pk = rsa.generate_private_key(65537, key_size, default_backend()) pkn = pk.private_numbers() self.n = MPI(pkn.public_numbers.n) self.e = MPI(pkn.public_numbers.e) self.d = MPI(pkn.d) self.p = MPI(pkn.p) self.q = MPI(pkn.q) # from the RFC: # "- MPI of u, the multiplicative inverse of p, mod q." # or, simply, p^-1 mod p # rsa.rsa_crt_iqmp(p, q) normally computes q^-1 mod p, # so if we swap the values around we get the answer we want self.u = MPI(rsa.rsa_crt_iqmp(pkn.q, pkn.p)) del pkn del pk self._compute_chksum()
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 __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())