def modinv(a, m): gcd, x, y = egcd(a, m) if gcd != 1: return None # modular inverse does not exist else: return x % m n = 8464481006489090994506453371545747140045883416875197642486592854169 p = 2209828846356855715679030504831459 #p = 3830378547390089828095201542724691 e = 3 q = int(n // p) phi_n = (p - 1) * (q - 1) d = modinv(e, phi_n) dmp1 = rsa.rsa_crt_dmp1(d, p) dmq1 = rsa.rsa_crt_dmq1(d, q) iqmp = rsa.rsa_crt_iqmp(p, q) pn = rsa.RSAPublicNumbers(e, n) compositen = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pn) compositek = compositen.private_key(backend=default_backend()) pem = compositek.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()) f = open("privateSmallKey.pem", "wb") f.write(pem) f.close()
def _encrypt_RSA(self, modulus, passphrase, text): public_numbers = rsa.RSAPublicNumbers(passphrase, modulus) public_key = public_numbers.public_key(default_backend()) ciphertext = public_key.encrypt(text.encode('ascii'), padding.PKCS1v15()) return ciphertext
def _rsa_pub(self): e = self._decode_int(self._params['e']) n = self._decode_int(self._params['n']) return rsa.RSAPublicNumbers(e, n)
def verify(self, message, signature): rsa.RSAPublicNumbers(bytes2int(self[-2]), bytes2int( self[-1])).public_key(default_backend()).verify( signature, message, padding.PKCS1v15(), hashes.SHA256())
def public_numbers(self): e = int.from_bytes(self.kv_key.key.e, byteorder='big') n = int.from_bytes(self.kv_key.key.n, byteorder='big') return rsa.RSAPublicNumbers(e, n)
def jwk_to_rsa(key): """Convert a deserialized JWK into an RSA Public Key instance.""" e = int.from_bytes(b64dec(key['e']), 'big') n = int.from_bytes(b64dec(key['n']), 'big') return rsa.RSAPublicNumbers(e, n).public_key(default_backend())
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') # 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
def __pubkey__(self): return rsa.RSAPublicNumbers(self.e, self.n).public_key(default_backend())
def updateWith(self, pubkey): self.modulus = pubkey.modulus.val self.modulusLen = len(binrepr(pubkey.modulus.val)) self.pubExp = pubkey.publicExponent.val self.key = rsa.RSAPublicNumbers( n=self.modulus, e=self.pubExp).public_key(default_backend())
def symmetric_decrypt(text: bytes, key: bytes) -> bytes: cipher = Cipher(algorithms.AES(key), modes.ECB()) decryptor = cipher.decryptor() iv = decryptor.update(text[:16]) decryptor.finalize() cipher = Cipher(algorithms.AES(key), modes.CBC(iv)) decryptor = cipher.decryptor() return unpad(decryptor.update(text[16:])) STEAM_PUBLIC_KEY: Final = rsa.RSAPublicNumbers( 17, int("1572435756163492767473017547683098671778311221560259237468446760604065883521072242173339019599191749864" "5577395742561473053175122897795413393419038630648254894306773660858554891146738442477393264257606729213" "7056263003121836768211312089498275802694267916711103128551999842076575732754013467986241640244933837449" ), ) def verify_signature(data: bytes, signature: bytes) -> bool: try: STEAM_PUBLIC_KEY.public_key().verify(signature, data, padding.PKCS1v15(), hashes.SHA1()) except InvalidSignature: return False else: return True
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())
def create_public_key(e, n): return rsa.RSAPublicNumbers(e, n).public_key(default_backend())
def _rsa_pub(self): e = self._decode_int(self.get('e')) n = self._decode_int(self.get('n')) return rsa.RSAPublicNumbers(e, n)
+ "2125876646350225386205170869478762584625481559337889894643589498753324189655838737003231877149808" + "0769782782986004968223577252545632595856348578972986803087375151523130980468315658731145540661959" + "6050525545290045046944269076387765616800870979827653118293545195314596061160131055834487112435567" + "4188026149535089147013264878621144892167844471212662659174643958985053020651238408715157877344829" + "6332175379863190146700888623219388047354669492295105275244771100851445677743253407525918517909312" + "1064757322245873728715200541955720319721861626588734157728068815156326358980514571916869090216857" + "1674529819233099030185697193927748667568997849788205951188943230054712902846136235791743994018772" + "7474047360851939145847078056327450140607700002648843419498134708391530606499524381440473803469993" + "9125774781194053568746989605638413082541876600142556111173865505734416200456890738357199900214109" + "565602296409823349451352963303084528108078854673626645830490080013931") e = 65537 key = rsa.RSAPublicNumbers(e, int(N)).public_key(default_backend()) token = "Some test bytes.".encode('utf-8') encrypted_token = key.encrypt( token, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None)) with open("token.txt", 'w') as file: file.write(str(b64encode(encrypted_token), encoding='utf-8'))
def build_vectors(mgf1alg, hashalg, filename): vectors = load_vectors_from_file(filename, load_pkcs1_vectors) output = [] for vector in vectors: # RSA keys for this must be long enough to accommodate the length of # the underlying hash function. This means we can't use the keys from # the sha1 test vectors for sha512 tests because 1024-bit keys are too # small. Instead we parse the vectors for the test cases, then # generate our own 2048-bit keys for each. private, _ = vector skey = rsa.generate_private_key(65537, 2048, backend) pn = skey.private_numbers() examples = private["examples"] output.append(b"# =============================================") output.append(b"# Example") output.append(b"# Public key") output.append(b"# Modulus:") output.append(format(pn.public_numbers.n, "x")) output.append(b"# Exponent:") output.append(format(pn.public_numbers.e, "x")) output.append(b"# Private key") output.append(b"# Modulus:") output.append(format(pn.public_numbers.n, "x")) output.append(b"# Public exponent:") output.append(format(pn.public_numbers.e, "x")) output.append(b"# Exponent:") output.append(format(pn.d, "x")) output.append(b"# Prime 1:") output.append(format(pn.p, "x")) output.append(b"# Prime 2:") output.append(format(pn.q, "x")) output.append(b"# Prime exponent 1:") output.append(format(pn.dmp1, "x")) output.append(b"# Prime exponent 2:") output.append(format(pn.dmq1, "x")) output.append(b"# Coefficient:") output.append(format(pn.iqmp, "x")) pkey = skey.public_key() vectorkey = rsa.RSAPrivateNumbers( p=private["p"], q=private["q"], d=private["private_exponent"], dmp1=private["dmp1"], dmq1=private["dmq1"], iqmp=private["iqmp"], public_numbers=rsa.RSAPublicNumbers( e=private["public_exponent"], n=private["modulus"])).private_key(backend) count = 1 for example in examples: message = vectorkey.decrypt( binascii.unhexlify(example["encryption"]), padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None)) assert message == binascii.unhexlify(example["message"]) ct = pkey.encrypt( message, padding.OAEP(mgf=padding.MGF1(algorithm=mgf1alg), algorithm=hashalg, label=None)) output.append(b"# OAEP Example {0} alg={1} mgf1={2}".format( count, hashalg.name, mgf1alg.name)) count += 1 output.append(b"# Message:") output.append(example["message"]) output.append(b"# Encryption:") output.append(binascii.hexlify(ct)) return b"\n".join(output)
def key_from_jwk_dict(jwk_dict, private=None): """Load JWK from dictionary :param jwk_dict: Dictionary representing a JWK """ # uncouple from the original item _jwk_dict = copy.copy(jwk_dict) if 'kty' not in _jwk_dict: raise MissingValue('kty missing') if _jwk_dict['kty'] == 'EC': ensure_ec_params(_jwk_dict, private) if private is not None and not private: # remove private components for v in EC_PRIVATE: _jwk_dict.pop(v, None) if _jwk_dict["crv"] in NIST2SEC: curve = NIST2SEC[_jwk_dict["crv"]]() else: raise UnsupportedAlgorithm( "Unknown curve: %s" % (_jwk_dict["crv"])) if _jwk_dict.get("d", None) is not None: # Ecdsa private key. _jwk_dict['priv_key'] = ec.derive_private_key( base64url_to_long(_jwk_dict["d"]), curve, backends.default_backend()) _jwk_dict['pub_key'] = _jwk_dict['priv_key'].public_key() else: # Ecdsa public key. ec_pub_numbers = ec.EllipticCurvePublicNumbers( base64url_to_long(_jwk_dict["x"]), base64url_to_long(_jwk_dict["y"]), curve) _jwk_dict['pub_key'] = ec_pub_numbers.public_key( backends.default_backend()) return ECKey(**_jwk_dict) elif _jwk_dict['kty'] == 'RSA': ensure_rsa_params(_jwk_dict, private) if private is not None and not private: # remove private components for v in RSA_PRIVATE: _jwk_dict.pop(v, None) rsa_pub_numbers = rsa.RSAPublicNumbers( base64url_to_long(_jwk_dict["e"]), base64url_to_long(_jwk_dict["n"])) if _jwk_dict.get("p", None) is not None: # Rsa private key. These MUST be present p_long = base64url_to_long(_jwk_dict["p"]) q_long = base64url_to_long(_jwk_dict["q"]) d_long = base64url_to_long(_jwk_dict["d"]) # If not present these can be calculated from the others if 'dp' not in _jwk_dict: dp_long = rsa_crt_dmp1(d_long, p_long) else: dp_long = base64url_to_long(_jwk_dict["dp"]) if 'dq' not in _jwk_dict: dq_long = rsa_crt_dmq1(d_long, q_long) else: dq_long = base64url_to_long(_jwk_dict["dq"]) if 'qi' not in _jwk_dict: qi_long = rsa_crt_iqmp(p_long, q_long) else: qi_long = base64url_to_long(_jwk_dict["qi"]) rsa_priv_numbers = rsa.RSAPrivateNumbers( p_long, q_long, d_long, dp_long, dq_long, qi_long, rsa_pub_numbers) _jwk_dict['priv_key'] = rsa_priv_numbers.private_key( backends.default_backend()) _jwk_dict['pub_key'] = _jwk_dict['priv_key'].public_key() else: _jwk_dict['pub_key'] = rsa_pub_numbers.public_key( backends.default_backend()) if _jwk_dict['kty'] != "RSA": raise WrongKeyType('"{}" should have been "RSA"'.format(_jwk_dict[ 'kty'])) return RSAKey(**_jwk_dict) elif _jwk_dict['kty'] == 'oct': if 'key' not in _jwk_dict and 'k' not in _jwk_dict: raise MissingValue( 'There has to be one of "k" or "key" in a symmetric key') return SYMKey(**_jwk_dict) else: raise UnknownKeyType
def decodeAdyenPublicKey(encoded_public_key): backend = default_backend() key_components = encoded_public_key.split("|") public_number = rsa.RSAPublicNumbers(int(key_components[0], 16), int(key_components[1], 16)) return backend.load_rsa_public_numbers(public_number)
def rsa_construct_public(numbers): rpn = rsa.RSAPublicNumbers(**numbers) return rpn.public_key(default_backend())
def key_exchange(self): """Do a whole key exchange, as described in RFC 4253""" self.logger.info("Exchange key mechanism activated...") # Generate a dh object for the key exchange and pick a random session cookie self.dh = asym_algos.EcdhSha2Nistp256() cookie = os.urandom(16) # Key Exchange Init: exchange the supported crypto algorithms, first algo in list is preferred one client_kexinit = KexInit(cookie=cookie, kex_algo=("ecdh-sha2-nistp256", ), server_host_key_algo=tuple( AuthenticationKey.known_key_types.keys()), encryption_algo_ctos=("aes128-ctr", ), encryption_algo_stoc=("aes128-ctr", ), mac_algo_ctos=("hmac-sha2-256", ), mac_algo_stoc=("hmac-sha2-256", ), compression_algo_ctos=("none", ), compression_algo_stoc=("none", ), languages_ctos=(), languages_stoc=(), first_kex_packet_follows=False) self.socket.send_ssh_msg(client_kexinit) server_kexinit = self.socket.recv_ssh_msg() if not isinstance(server_kexinit, KexInit): raise Exception("First packet is not a KEI packet") self.logger.info("Key Exchange Init phase: ok") # Key Exchange Diffie-Hellman: create a shared secret client_kex_ecdh = KexDHInit( e=asym_algos.EcdhSha2Nistp256.to_point_encoding( self.dh.client_ephemeral_public_key)) self.socket.send_ssh_msg(client_kex_ecdh) server_kex_ecdh = self.socket.recv_ssh_msg() if not isinstance(server_kex_ecdh, KexDHReply): raise Exception("not a KEXDH_REPLY packet") self.server_key = AuthenticationKey.from_blob( server_kex_ecdh.server_public_key) kex_hash_algo = hash_algos.Sha256( ) # Currently forced. TODO: make it modifiable # construct a 'public key' object from the received server public key self.dh.server_ephemeral_public_key = \ ec.EllipticCurvePublicKey.from_encoded_point(self.dh.curve, server_kex_ecdh.f) # multiply server's ephemeral public key with client's ephemeral private key --> shared secret shared_secret = self.dh.compute_shared_secret() self.logger.info("Key Exchange Diffie-Hellman phase: ok") # Compute exchange hash class ExchangeHash(BinarySshPacket): # Not really a SSH packet, but we use the same method to get the payload. __slots__ = ('client_version', 'server_version', 'client_kexinit', 'server_kexinit', 'host_key', 'client_exchange_value', 'server_exchange_value', 'shared_secret') _field_types = (StringType('ascii'), StringType('ascii'), StringType('octet'), StringType('octet'), StringType('octet'), StringType('octet'), StringType('octet'), MpintType()) client_kexinit_bytes = client_kexinit.msg_type.to_bytes( 1, 'big') + client_kexinit.payload() server_kexinit_bytes = server_kexinit.msg_type.to_bytes( 1, 'big') + server_kexinit.payload() to_be_hashed = ExchangeHash(client_version=self.client_version, server_version=self.server_version, client_kexinit=client_kexinit_bytes, server_kexinit=server_kexinit_bytes, host_key=server_kex_ecdh.server_public_key, client_exchange_value=client_kex_ecdh.e, server_exchange_value=server_kex_ecdh.f, shared_secret=int.from_bytes(shared_secret, 'big', signed=False)) key_exchange_hash = kex_hash_algo.hash(to_be_hashed.payload()) # Set the session ID: # > The exchange hash H from the first key exchange is additionally # > used as the session identifier [...] Once computed, the session # > identifier is not changed, even if keys are later re-exchanged # > [RFC4253] if self._session_id is None: self._session_id = key_exchange_hash # Verify server's signature server_public_key_iterator = server_kex_ecdh.server_public_key.__iter__( ) key_type = fields.StringType('ascii').from_bytes( server_public_key_iterator) # TODO: support other key types. Here, only ssh-rsa keys are supported. assert key_type == 'ssh-rsa' rsa_exponent = fields.MpintType().from_bytes( server_public_key_iterator) rsa_modulus = fields.MpintType().from_bytes(server_public_key_iterator) server_key = rsa.RSAPublicNumbers( e=rsa_exponent, n=rsa_modulus).public_key(default_backend()) server_signature_iterator = server_kex_ecdh.signature.__iter__() key_type = fields.StringType('ascii').from_bytes( server_signature_iterator) # TODO: support other key types. Here, only ssh-rsa keys are supported. assert key_type == 'ssh-rsa' signature = fields.StringType('octet').from_bytes( server_signature_iterator) server_key.verify(signature, key_exchange_hash, padding.PKCS1v15(), hashes.SHA1()) self.logger.info("Server signature verification: ok") # New Keys: switch to the new cyphering method self.socket.send_ssh_msg(NewKeys()) nk = self.socket.recv_ssh_msg() if not isinstance(nk, NewKeys): raise Exception("not a NEWKEYS packet") # Activate the encryption self.socket.change_keys(kex_hash_algo, shared_secret, key_exchange_hash, self.session_id) self.logger.info("Keys and algorithms change: ok")
# Parsing of the cmd line arguments if encrypting: N = int(sys.argv[1], 16) e = int(sys.argv[2], 16) message = binascii.unhexlify(sys.argv[3]) else: P1 = int(sys.argv[1], 16) P2 = int(sys.argv[2], 16) e = int(sys.argv[3], 16) d = int(sys.argv[4], 16) message = binascii.unhexlify(sys.argv[5]) # Setup of the keys if encrypting: pk = rsa.RSAPublicNumbers(e, N).public_key(default_backend()) else: pky = rsa.RSAPrivateNumbers( public_numbers=rsa.RSAPublicNumbers(e, P1*P2), p=P1, q=P2, d=d, dmp1=rsa.rsa_crt_dmp1(d, P1), dmq1=rsa.rsa_crt_dmq1(d, P2), iqmp=rsa.rsa_crt_iqmp(P1, P2)).private_key(default_backend()) # Actual encryption/decryption if encrypting: ciphertext = pk.encrypt( message, padding.OAEP(
def _fromString_PRIVATE_OPENSSH(cls, data, passphrase): """ Return a private key object corresponding to this OpenSSH private key string. If the key is encrypted, passphrase MUST be provided. Providing a passphrase for an unencrypted key is an error. The format of an OpenSSH private key string is:: -----BEGIN <key type> PRIVATE KEY----- [Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,<initialization value>] <base64-encoded ASN.1 structure> ------END <key type> PRIVATE KEY------ The ASN.1 structure of a RSA key is:: (0, n, e, d, p, q) The ASN.1 structure of a DSA key is:: (0, p, q, g, y, x) The ASN.1 structure of a ECDSA key is:: (ECParameters, OID, NULL) @type data: L{bytes} @param data: The key data. @type passphrase: L{bytes} or L{None} @param passphrase: The passphrase the key is encrypted with, or L{None} if it is not encrypted. @return: A new key. @rtype: L{twisted.conch.ssh.keys.Key} @raises BadKeyError: if * a passphrase is provided for an unencrypted key * the ASN.1 encoding is incorrect @raises EncryptedKeyError: if * a passphrase is not provided for an encrypted key """ lines = data.strip().splitlines() kind = lines[0][11:-17] if lines[1].startswith(b'Proc-Type: 4,ENCRYPTED'): if not passphrase: raise EncryptedKeyError('Passphrase must be provided ' 'for an encrypted key') # Determine cipher and initialization vector try: _, cipherIVInfo = lines[2].split(b' ', 1) cipher, ivdata = cipherIVInfo.rstrip().split(b',', 1) except ValueError: raise BadKeyError('invalid DEK-info %r' % (lines[2],)) if cipher in (b'AES-128-CBC', b'AES-256-CBC'): algorithmClass = algorithms.AES keySize = int(int(cipher.split(b'-')[1])/8) if len(ivdata) != 32: raise BadKeyError('AES encrypted key with a bad IV') elif cipher == b'DES-EDE3-CBC': algorithmClass = algorithms.TripleDES keySize = 24 if len(ivdata) != 16: raise BadKeyError('DES encrypted key with a bad IV') else: raise BadKeyError('unknown encryption type %r' % (cipher,)) # Extract keyData for decoding iv = bytes(bytearray([int(ivdata[i:i + 2], 16) for i in range(0, len(ivdata), 2)])) ba = md5(passphrase + iv[:8]).digest() bb = md5(ba + passphrase + iv[:8]).digest() decKey = (ba + bb)[:keySize] b64Data = decodebytes(b''.join(lines[3:-1])) decryptor = Cipher( algorithmClass(decKey), modes.CBC(iv), backend=default_backend() ).decryptor() keyData = decryptor.update(b64Data) + decryptor.finalize() removeLen = ord(keyData[-1:]) keyData = keyData[:-removeLen] else: b64Data = b''.join(lines[1:-1]) keyData = decodebytes(b64Data) try: decodedKey = berDecoder.decode(keyData)[0] except PyAsn1Error as e: raise BadKeyError( 'Failed to decode key (Bad Passphrase?): %s' % (e,)) if kind == b'EC': return cls( load_pem_private_key(data, passphrase, default_backend())) if kind == b'RSA': if len(decodedKey) == 2: # Alternate RSA key decodedKey = decodedKey[0] if len(decodedKey) < 6: raise BadKeyError('RSA key failed to decode properly') n, e, d, p, q, dmp1, dmq1, iqmp = [ long(value) for value in decodedKey[1:9] ] if p > q: # Make p smaller than q p, q = q, p return cls( rsa.RSAPrivateNumbers( p=p, q=q, d=d, dmp1=dmp1, dmq1=dmq1, iqmp=iqmp, public_numbers=rsa.RSAPublicNumbers(e=e, n=n), ).private_key(default_backend()) ) elif kind == b'DSA': p, q, g, y, x = [long(value) for value in decodedKey[1: 6]] if len(decodedKey) < 6: raise BadKeyError('DSA key failed to decode properly') return cls( dsa.DSAPrivateNumbers( x=x, public_numbers=dsa.DSAPublicNumbers( y=y, parameter_numbers=dsa.DSAParameterNumbers( p=p, q=q, g=g ) ) ).private_key(backend=default_backend()) ) else: raise BadKeyError("unknown key type %s" % (kind,))
def _read_single_json_key(cls, parsed_key): """Reads a parsed json key and transform it to Jwk key. The key format is defined at https://tools.ietf.org/html/rfc7518#section-6. Args: parsed_key: a Python reprenstation of Json object. Raises: UnsupportedAlgorithm: if the key type is not supported. Returns: A Jwk key. """ key_type = parsed_key["kty"] algorithm = parsed_key.get("alg", "") if not algorithm: raise exceptions.UnsupportedAlgorithm("Alg field is missing") if algorithm not in [ "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512" ]: raise exceptions.UnsupportedAlgorithm("Unknown algorithm: %s" % (algorithm)) if key_type == "RSA": rsa_pub_numbers = rsa.RSAPublicNumbers( jwsutil.b64_to_int(parsed_key["e"]), jwsutil.b64_to_int(parsed_key["n"])) if parsed_key.get("p", None) is not None: # Rsa private key. rsa_priv_numbers = rsa.RSAPrivateNumbers( jwsutil.b64_to_int(parsed_key["p"]), jwsutil.b64_to_int(parsed_key["q"]), jwsutil.b64_to_int(parsed_key["d"]), jwsutil.b64_to_int(parsed_key["dp"]), jwsutil.b64_to_int(parsed_key["dq"]), jwsutil.b64_to_int(parsed_key["qi"]), rsa_pub_numbers) priv_key = rsa_priv_numbers.private_key( backends.default_backend()) return Jwk(key_type, parsed_key.get("kid", ""), algorithm, None, priv_key, priv_key.public_key()) else: # Rsa public key. return Jwk( key_type, parsed_key.get("kid", ""), algorithm, None, None, rsa_pub_numbers.public_key(backends.default_backend())) elif key_type == "EC": if parsed_key["crv"] == "P-256": curve = ec.SECP256R1() elif parsed_key["crv"] == "P-384": curve = ec.SECP384R1() elif parsed_key["crv"] == "P-521": curve = ec.SECP521R1() else: raise exceptions.UnsupportedAlgorithm("Unknown curve: %s" % (parsed_key["crv"])) if parsed_key.get("d", None) is not None: # Ecdsa private key. priv_key = ec.derive_private_key( jwsutil.b64_to_int(parsed_key["d"]), curve, backends.default_backend()) return Jwk(key_type, parsed_key.get("kid", ""), algorithm, None, priv_key, priv_key.public_key()) else: # Ecdsa public key. ec_pub_numbers = ec.EllipticCurvePublicNumbers( jwsutil.b64_to_int(parsed_key["x"]), jwsutil.b64_to_int(parsed_key["y"]), curve) pub_key = ec_pub_numbers.public_key(backends.default_backend()) return Jwk(key_type, parsed_key.get("kid", ""), algorithm, None, None, pub_key) elif key_type == "oct": sym_key = jwsutil.urlsafe_b64decode(parsed_key["k"]) return Jwk(key_type, parsed_key.get("kid", ""), algorithm, sym_key) else: raise exceptions.UnsupportedAlgorithm("Unsupported key type: %s" % (key_type))
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import serialization p = 12710704528284626658156805778821852382103996398260119866833530161861047758694507696668550948760328371763601085231764022077721271789239494299392005238563967 q = 10971495673542452647230717494161230638467424498902156978693581279774991083067154896487136489032000184434746556548127060645863633294998522190328312852934089 n = p * q e = 65537 d = 97035979111221694229356344139648102993473235782030168979539666727177265783733342530447515369511948144576833774688176003372429188585596095809976942441427392990151026528187482014094117335842544863877086096454548134790624549504097689049787678262608825586139911442930809194643080765014416542915984075625821257441 dmp1 = 10449282510191049795711036894358681977976059538109167005895755138785535958240139023351870233095201362367937740040461879815697834203409619518262097231153559 dmq1 = 5358433152551182146460179830524935079055576595829229909425578674688159582935036604158876127087542333390105860536680820866881352129427845312846615466022465 iqmp = 293850525884800098939874471896584900656239343004543921433799219061333103951726554625988684331746104214985079136614128680288250787842032235537287760514941 ciphertext = b"Qe7+h9OPQ7PN9CmF0ZOmD32fwpJotrUL67zxdRvhBn2U3fDtoz4iUGRXNOxwUXdJ2Cmz7zjS0DE8ST5dozBysByz/u1H//iAN+QeGlFVaS1Ee5a/TZilrTCbGPWxfNY4vRXHP6CB82QxhMjQ7/x90/+JLrhdAO99lvmdNetGZjY=" pub_nums = rsa.RSAPublicNumbers(e, n) priv_nums = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp, pub_nums) backend = default_backend() pub_key = backend.load_rsa_public_numbers(pub_nums) priv_key = backend.load_rsa_private_numbers(priv_nums) # plaintext = priv_key.decrypt(ciphertext, padding.OAEP(padding.MGF1(hashes.SHA1()), hashes.SHA1(), label=None)) # print("Plaintext:", plaintext) pem = priv_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL,
def from_key(cls, key: PublicKey) -> RsaPublicKey: if not isinstance(key, rsa.RsaPublicKey): raise TypeError() return cls(cr_rsa.RSAPublicNumbers(key.public_exponent, key.modulus).public_key(backend))
def _rsa_pub(self, k): return rsa.RSAPublicNumbers(self._decode_int(k['e']), self._decode_int(k['n']))
def _get_issuer_publickey(issuer, key_id=None, insecure=False): """ :return: Tuple containing (public_key, cache_lifetime). Cache_lifetime how the public key is valid """ # Set the user agent so Cloudflare isn't mad at us headers = {'User-Agent': 'SciTokens/{}'.format(PKG_VERSION)} # Go to the issuer's website, and download the OAuth well known bits # https://tools.ietf.org/html/draft-ietf-oauth-discovery-07 well_known_uri = ".well-known/openid-configuration" if not issuer.endswith("/"): issuer = issuer + "/" parsed_url = urlparse.urlparse(issuer) updated_url = urlparse.urljoin(parsed_url.path, well_known_uri) parsed_url_list = list(parsed_url) parsed_url_list[2] = updated_url meta_uri = urlparse.urlunparse(parsed_url_list) # Make sure the protocol is https if not insecure: parsed_url = urlparse.urlparse(meta_uri) if parsed_url.scheme != "https": raise NonHTTPSIssuer( "Issuer is not over HTTPS. RFC requires it to be over HTTPS" ) response = request.urlopen(request.Request(meta_uri, headers=headers)) data = json.loads(response.read().decode('utf-8')) # Get the keys URL from the openid-configuration jwks_uri = data['jwks_uri'] # Now, get the keys if not insecure: parsed_url = urlparse.urlparse(jwks_uri) if parsed_url.scheme != "https": raise NonHTTPSIssuer("jwks_uri is not over HTTPS, insecure!") response = request.urlopen(request.Request(jwks_uri, headers=headers)) # Get the cache data from the headers cache_timer = 0 headers = response.info() if "Cache-Control" in headers: # Parse out the max-age, if it's there. if "max-age" in headers['Cache-Control']: match = re.search(r".*max-age=(\d+)", headers['Cache-Control']) if match: cache_timer = int(match.group(1)) # Minimum cache time of 10 minutes, no matter what the remote says cache_timer = max(cache_timer, config.get_int("cache_lifetime")) keys_data = json.loads(response.read().decode('utf-8')) # Loop through each key, looking for the right key id public_key = "" raw_key = None # If there is no kid in the header, then just take the first key? if key_id == None: if len(keys_data['keys']) != 1: raise NotImplementedError( "No kid in header, but multiple keys in " "response from certs server. Don't know which key to use!" ) else: raw_key = keys_data['keys'][0] else: # Find the right key for key in keys_data['keys']: if key['kid'] == key_id: raw_key = key break if raw_key == None: raise MissingKeyException( "Unable to find key at issuer {}".format(jwks_uri)) if raw_key['kty'] == "RSA": public_key_numbers = rsa.RSAPublicNumbers( long_from_bytes(raw_key['e']), long_from_bytes(raw_key['n'])) public_key = public_key_numbers.public_key( backends.default_backend()) elif raw_key['kty'] == 'EC': public_key_numbers = ec.EllipticCurvePublicNumbers( long_from_bytes(raw_key['x']), long_from_bytes(raw_key['y']), ec.SECP256R1()) public_key = public_key_numbers.public_key( backends.default_backend()) else: raise UnsupportedKeyException( "SciToken signed with an unsupported key type") return public_key, cache_timer
def public_numbers(self): return rsa.RSAPublicNumbers( e=self._backend._bn_to_int(self._rsa_cdata.e), n=self._backend._bn_to_int(self._rsa_cdata.n), )
def populate_public_key(e, n): key = rsa.RSAPublicNumbers(e, n).public_key(default_backend()) return key
def load_public(self, key_type, data, backend): """Make RSA public key from data.""" (e, n), data = self.get_public(data) public_numbers = rsa.RSAPublicNumbers(e, n) public_key = public_numbers.public_key(backend) return public_key, data
dec = asymkey.decrypt_oaep(ciphertext, hash=hashtype(), mgf_hash=mgf1hash()) assert data == dec asymkey.delete() OAEP_VECTOR_KEY = rsa.RSAPrivateNumbers( p=0xECF5AECD1E5515FFFACBD75A2816C6EBF49018CDFB4638E185D66A7396B6F8090F8018C7FD95CC34B857DC17F0CC6516BB1346AB4D582CADAD7B4103352387B70338D084047C9D9539B6496204B3DD6EA442499207BEC01F964287FF6336C3984658336846F56E46861881C10233D2176BF15A5E96DDC780BC868AA77D3CE769, # noqa: E501 q=0xBC46C464FC6AC4CA783B0EB08A3C841B772F7E9B2F28BABD588AE885E1A0C61E4858A0FB25AC299990F35BE85164C259BA1175CDD7192707135184992B6C29B746DD0D2CABE142835F7D148CC161524B4A09946D48B828473F1CE76B6CB6886C345C03E05F41D51B5C3A90A3F24073C7D74A4FE25D9CF21C75960F3FC3863183, # noqa: E501 d=0x056B04216FE5F354AC77250A4B6B0C8525A85C59B0BD80C56450A22D5F438E596A333AA875E291DD43F48CB88B9D5FC0D499F9FCD1C397F9AFC070CD9E398C8D19E61DB7C7410A6B2675DFBF5D345B804D201ADD502D5CE2DFCB091CE9997BBEBE57306F383E4D588103F036F7E85D1934D152A323E4A8DB451D6F4A5B1B0F102CC150E02FEEE2B88DEA4AD4C1BACCB24D84072D14E1D24A6771F7408EE30564FB86D4393A34BCF0B788501D193303F13A2284B001F0F649EAF79328D4AC5C430AB4414920A9460ED1B7BC40EC653E876D09ABC509AE45B525190116A0C26101848298509C1C3BF3A483E7274054E15E97075036E989F60932807B5257751E79, # noqa: E501 dmp1=0xC73564571D00FB15D08A3DE9957A50915D7126E9442DACF42BC82E862E5673FF6A008ED4D2E374617DF89F17A160B43B7FDA9CB6B6B74218609815F7D45CA263C159AA32D272D127FAF4BC8CA2D77378E8AEB19B0AD7DA3CB3DE0AE7314980F62B6D4B0A875D1DF03C1BAE39CCD833EF6CD7E2D9528BF084D1F969E794E9F6C1, # noqa: E501 dmq1=0x2658B37F6DF9C1030BE1DB68117FA9D87E39EA2B693B7E6D3A2F70947413EEC6142E18FB8DFCB6AC545D7C86A0AD48F8457170F0EFB26BC48126C53EFD1D16920198DC2A1107DC282DB6A80CD3062360BA3FA13F70E4312FF1A6CD6B8FC4CD9C5C3DB17C6D6A57212F73AE29F619327BAD59B153858585BA4E28B60A62A45E49, # noqa: E501 iqmp=0x6F38526B3925085534EF3E415A836EDE8B86158A2C7CBFECCB0BD834304FEC683BA8D4F479C433D43416E63269623CEA100776D85AFF401D3FFF610EE65411CE3B1363D63A9709EEDE42647CEA561493D54570A879C18682CD97710B96205EC31117D73B5F36223FADD6E8BA90DD7C0EE61D44E163251E20C7F66EB305117CB8, # noqa: E501 public_numbers=rsa.RSAPublicNumbers( n=0xAE45ED5601CEC6B8CC05F803935C674DDBE0D75C4C09FD7951FC6B0CAEC313A8DF39970C518BFFBA5ED68F3F0D7F22A4029D413F1AE07E4EBE9E4177CE23E7F5404B569E4EE1BDCF3C1FB03EF113802D4F855EB9B5134B5A7C8085ADCAE6FA2FA1417EC3763BE171B0C62B760EDE23C12AD92B980884C641F5A8FAC26BDAD4A03381A22FE1B754885094C82506D4019A535A286AFEB271BB9BA592DE18DCF600C2AEEAE56E02F7CF79FC14CF3BDC7CD84FEBBBF950CA90304B2219A7AA063AEFA2C3C1980E560CD64AFE779585B6107657B957857EFDE6010988AB7DE417FC88D8F384C4E6E72C3F943E0C31C0C4A5CC36F879D8A3AC9D7D59860EAADA6B83BB, # noqa: E501 e=0x10001, ), ).private_key(default_backend()) OAEP_VECTORS = [ { "msg": b"\x8b\xba\x6b\xf8\x2a\x6c\x0f\x86\xd5\xf1\x75\x6e\x97\x95\x68\x70\xb0\x89\x53\xb0\x6b\x4e\xb2\x05\xbc\x16\x94\xee", # noqa: E501 "enc": b"\x53\xea\x5d\xc0\x8c\xd2\x60\xfb\x3b\x85\x85\x67\x28\x7f\xa9\x15\x52\xc3\x0b\x2f\xeb\xfb\xa2\x13\xf0\xae\x87\x70\x2d\x06\x8d\x19\xba\xb0\x7f\xe5\x74\x52\x3d\xfb\x42\x13\x9d\x68\xc3\xc5\xaf\xee\xe0\xbf\xe4\xcb\x79\x69\xcb\xf3\x82\xb8\x04\xd6\xe6\x13\x96\x14\x4e\x2d\x0e\x60\x74\x1f\x89\x93\xc3\x01\x4b\x58\xb9\xb1\x95\x7a\x8b\xab\xcd\x23\xaf\x85\x4f\x4c\x35\x6f\xb1\x66\x2a\xa7\x2b\xfc\xc7\xe5\x86\x55\x9d\xc4\x28\x0d\x16\x0c\x12\x67\x85\xa7\x23\xeb\xee\xbe\xff\x71\xf1\x15\x94\x44\x0a\xae\xf8\x7d\x10\x79\x3a\x87\x74\xa2\x39\xd4\xa0\x4c\x87\xfe\x14\x67\xb9\xda\xf8\x52\x08\xec\x6c\x72\x55\x79\x4a\x96\xcc\x29\x14\x2f\x9a\x8b\xd4\x18\xe3\xc1\xfd\x67\x34\x4b\x0c\xd0\x82\x9d\xf3\xb2\xbe\xc6\x02\x53\x19\x62\x93\xc6\xb3\x4d\x3f\x75\xd3\x2f\x21\x3d\xd4\x5c\x62\x73\xd5\x05\xad\xf4\xcc\xed\x10\x57\xcb\x75\x8f\xc2\x6a\xee\xfa\x44\x12\x55\xed\x4e\x64\xc1\x99\xee\x07\x5e\x7f\x16\x64\x61\x82\xfd\xb4\x64\x73\x9b\x68\xab\x5d\xaf\xf0\xe6\x3e\x95\x52\x01\x68\x24\xf0\x54\xbf\x4d\x3c\x8c\x90\xa9\x7b\xb6\xb6\x55\x32\x84\xeb\x42\x9f\xcc", # noqa: E501 }, { "msg": b"\xe6\xad\x18\x1f\x05\x3b\x58\xa9\x04\xf2\x45\x75\x10\x37\x3e\x57", # noqa: E501 "enc": b"\xa2\xb1\xa4\x30\xa9\xd6\x57\xe2\xfa\x1c\x2b\xb5\xed\x43\xff\xb2\x5c\x05\xa3\x08\xfe\x90\x93\xc0\x10\x31\x79\x5f\x58\x74\x40\x01\x10\x82\x8a\xe5\x8f\xb9\xb5\x81\xce\x9d\xdd\xd3\xe5\x49\xae\x04\xa0\x98\x54\x59\xbd\xe6\xc6\x26\x59\x4e\x7b\x05\xdc\x42\x78\xb2\xa1\x46\x5c\x13\x68\x40\x88\x23\xc8\x5e\x96\xdc\x66\xc3\xa3\x09\x83\xc6\x39\x66\x4f\xc4\x56\x9a\x37\xfe\x21\xe5\xa1\x95\xb5\x77\x6e\xed\x2d\xf8\xd8\xd3\x61\xaf\x68\x6e\x75\x02\x29\xbb\xd6\x63\xf1\x61\x86\x8a\x50\x61\x5e\x0c\x33\x7b\xec\x0c\xa3\x5f\xec\x0b\xb1\x9c\x36\xeb\x2e\x0b\xbc\xc0\x58\x2f\xa1\xd9\x3a\xac\xdb\x06\x10\x63\xf5\x9f\x2c\xe1\xee\x43\x60\x5e\x5d\x89\xec\xa1\x83\xd2\xac\xdf\xe9\xf8\x10\x11\x02\x2a\xd3\xb4\x3a\x3d\xd4\x17\xda\xc9\x4b\x4e\x11\xea\x81\xb1\x92\x96\x6e\x96\x6b\x18\x20\x82\xe7\x19\x64\x60\x7b\x4f\x80\x02\xf3\x62\x99\x84\x4a\x11\xf2\xae\x0f\xae\xac\x2e\xae\x70\xf8\xf4\xf9\x80\x88\xac\xdc\xd0\xac\x55\x6e\x9f\xcc\xc5\x11\x52\x19\x08\xfa\xd2\x6f\x04\xc6\x42\x01\x45\x03\x05\x77\x87\x58\xb0\x53\x8b\xf8\xb5\xbb\x14\x4a\x82\x8e\x62\x97\x95", # noqa: E501 }, { "msg": b"\x51\x0a\x2c\xf6\x0e\x86\x6f\xa2\x34\x05\x53\xc9\x4e\xa3\x9f\xbc\x25\x63\x11\xe8\x3e\x94\x45\x4b\x41\x24", # noqa: E501