from cryptography.exceptions import InvalidSignature private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048) # $ PublicKeyGeneration keySize=2048 public_key = private_key.public_key() HASH_ALGORITHM = hashes.SHA256() # ------------------------------------------------------------------------------ # encrypt/decrypt # ------------------------------------------------------------------------------ print("encrypt/decrypt") ENCRYPT_PADDING = padding.OAEP( mgf=padding.MGF1(algorithm=HASH_ALGORITHM), algorithm=HASH_ALGORITHM, label=None, ) secret_message = b"secret message" # Following example at https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa.html#encryption encrypted = public_key.encrypt(secret_message, padding=ENCRYPT_PADDING) print("encrypted={}".format(encrypted)) print() decrypted = private_key.decrypt(encrypted, padding=ENCRYPT_PADDING)
def handshakepacket_received(self, packet): if self.mode == "server": if packet.status == 0: cert = x509.load_pem_x509_certificate(packet.cert, default_backend()) self.extract_public_client_key = cert.public_key() try: self.extract_public_client_key.verify( packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except: logger.debug("Server 1: wrong signature") new_secure_packet = HandshakePacket(status=2) self.transport.write(new_secure_packet.__serialize__()) self.transport.close() nonce = 10 self.server_private_key, self.data, self.RSA_private_key, server_signature, self.nonce_bytes = self.create_key( nonce) # Reveive nonceA nonce_client = str(packet.nonce).encode('ASCII') cert = self.create_cert(self.RSA_private_key) nonce_signature_server = self.RSA_private_key.sign( nonce_client, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) packet = HandshakePacket(status=1, pk=self.data, signature=server_signature, nonce=nonce, nonceSignature=nonce_signature_server, cert=cert) self.transport.write(packet.__serialize__()) elif packet.status == 1: try: self.extract_public_client_key.verify( packet.nonceSignature, self.nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception: logger.debug("Server 2: wrong signature") new_secure_packet = HandshakePacket(status=2) self.transport.write(new_secure_packet.__serialize__()) self.transport.close() print("crap Handshake complete") if self.mode == "client" and packet.status == 1: cert = x509.load_pem_x509_certificate(packet.cert, default_backend()) self.extract_public_server_key = cert.public_key() try: self.extract_public_server_key.verify( packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) self.extract_public_server_key.verify( packet.nonceSignature, self.nonceA, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception: logger.debug("client verify 1: wrong signature") new_secure_packet = HandshakePacket(status=2) self.transport.write(new_secure_packet.__serialize__()) self.transport.close() nonce_server = str(packet.nonce).encode('ASCII') nonce_signature_client = self.RSA_private_key.sign( nonce_server, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) packet = HandshakePacket(status=1, nonceSignature=nonce_signature_client) self.transport.write(packet.__serialize__())
def process(self, msg=b""): # Contador de mensagens aumenta self.msg_count += 1 # 1ª chamada à função if self.msg_count == -1: print('» Sending my public key...') # Envio da chave pública do cliente return cl_key_public_dh_bytes # Se receber a 1ª mensagem, trata-se da assinatura e da chave pública de DH do # servidor elif self.msg_count == 0: print('> Server [{}] sent its signature and public key.'.format( self.msg_count)) # Os primeiros 256 bytes estão reservados para a assinatura do servidor sv_signature = msg[:256] # Chave pública de DH do servidor sv_key_public_dh_bytes = msg[256:] sv_key_public_dh = load_pem_public_key(sv_key_public_dh_bytes, backend=default_backend()) # Mensagem a assinar, constituida por ambas as chaves públicas de DH self.sign_msg = sv_key_public_dh_bytes + cl_key_public_dh_bytes # Leitura da chave pública de RSA do servidor armazenada f = open('sv_key_public_rsa.txt', 'rb') sv_key_public_rsa_bytes = f.read() f.close() # Validação da chave pública de RSA do servidor try: sv_key_public_rsa = load_pem_public_key( sv_key_public_rsa_bytes, backend=default_backend()) except: print('» Invalid RSA key from Server!') return None # Verificação da assinatura do servidor através da sua chave pública de RSA try: sv_key_public_rsa.verify( sv_signature, self.sign_msg, apadding.PSS(mgf=apadding.MGF1(hashes.SHA256()), salt_length=apadding.PSS.MAX_LENGTH), hashes.SHA256()) print('» Server\'s signature accepted!') except: print('» Server\'s signature denied!') return None # Chave partilhada (gerada a partir da chave privada de DH do cliente e da # pública do servidor) key_shared = cl_key_private_dh.exchange(sv_key_public_dh) hkdf = HKDF(algorithm=hashes.SHA256(), length=64, salt=None, info=hkdf_info, backend=default_backend()) # Derivação da chave partilhada key_derived = hkdf.derive(key_shared) # Separação da chave derivada em chave de MAC e chave de encriptação e # desencriptação self.key_mac = key_derived[:32] self.key_enc = key_derived[32:64] # Leitura da chave privada de RSA do cliente armazenada f = open('cl_key_private_rsa.txt', 'rb') cl_key_private_rsa_bytes = f.read() f.close() # Validação da chave privada de RSA do cliente try: cl_key_private_rsa = serialization.load_pem_private_key( cl_key_private_rsa_bytes, password=None, backend=default_backend()) except: print('» Invalid private RSA key!') return None # Assinatura do cliente assinada pela sua chave privade de RSA cl_signature = cl_key_private_rsa.sign( self.sign_msg, apadding.PSS(mgf=apadding.MGF1(hashes.SHA256()), salt_length=apadding.PSS.MAX_LENGTH), hashes.SHA256()) # A partir da 2ª mensagem, trata-se de uma mensagem encriptada pelo cliente elif self.msg_count >= 1: # Separação da mensagem recebida (1ºs 32 bytes formam a tag do # MAC, os restantes formam a mensagem encriptada) msg_tag = msg[:32] msg_enc = msg[32:] # Verificação da tag da mensagem mac_check = unmac(msg_enc, self.key_mac, msg_tag) # Se a integridade da mensagem tiver sido atacada if not mac_check: print('» Server\'s message\'s integrity compromised!') return None else: # Desencriptação da mensagem msg_dec = decrypt(msg_enc, self.key_enc) # Se a confidencialidade da mensagem tiver sido atacada if not msg_dec: print( '» Server\'s message\'s confidentiality compromised!') return None else: # Unpadding da mensagem msg = unpad(msg_dec) text = msg.decode() print('> Server [{}]: "{}"'.format(self.msg_count, text)) print('» Input: ', end='') try: # Leitura de mensagem no terminal my_msg = input().encode() if my_msg == b'' or my_msg == b'nothing': return None # Se for detetado ^C, a mensagem "lida" é vazia except KeyboardInterrupt: print('') return None # Padding da mensagem msg_pad = pad(my_msg) # Encriptação da mensagem msg_enc = encrypt(msg_pad, self.key_enc) # Geração da tag da mensagem msg_tag = mac(msg_enc, self.key_mac) if self.msg_count == 0: return cl_signature + msg_tag + msg_enc # Concatenação da tag com a mensagem encriptada # se a introduzida não estiver vazia, caso contrário retorna 'None' else: return msg_tag + msg_enc
def cli(filename): """Send file over to server""" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = '127.0.0.1' port = 4567 click.echo(click.style('Connecting...', bold=True, fg='yellow')) try: s.connect((host, port)) except socket.error as msg: click.echo( click.style('Error connecting to server: ' + str(msg[1]), bold=True, fg='red')) pt = b"" while True: chunk = filename.read(100) if not chunk: break pt += chunk r_pkt = s.recv(2048) #click.echo(click.style('Client: public key = %s' % rsa_public_key, bold = True, fg = 'green')) so = SealedObject() pkt = so.deserialize(r_pkt) signature = pkt.get_attribute('sig') pem = pkt.msg rsa_public_key = serialization.load_pem_public_key( pem.encode(), backend=default_backend() ) #.public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo) key_bytes = rsa_public_key.public_bytes( serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo) verifier = rsa_public_key.verifier( signature, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) verifier.update(key_bytes) try: verifier.verify() except InvalidKey: click.echo(click.style('Error verifying key', bold=True, fg='red')) return sk = os.urandom(32) sk1 = sk[0:16] sk2 = sk[16:32] so = SealedObject() csk = so.seal_asym(sk, rsa_public_key) s.sendall(csk) cipher = ciphers.KeyAES(sk1, 'CFB8', False) ct = cipher.encrypt(pt) hmac = mac.MAC(sk2) mac1 = hmac.genMAC(ct, 0) pkt = packet.Packet(ct, mac1, cipher.iv) so = SealedObject() csk = so.serialize(pkt) s.send(csk) s.close() click.echo(click.style('File sent!', bold=True, fg='green'))
def get_file(): """Get key file""" global keys_obj global failct global private_key #look for quadski err, results = grasp.get_flood(asa_nonce, flood_obj) if not err: # results contains all the unexpired tagged objectives # but really there should only be one... if results == []: grasp.tprint("Found no value for", flood_obj.name) time.sleep(10) #pause for something to change... return else: grasp.tprint("Found value for", flood_obj.name) # recover quadski's public key quadski_pub_key = serialization.load_pem_public_key( results[0].objective.value, backend=default_backend()) else: grasp.tprint("get_flood failed", grasp.etext[err]) return #not this time #set up objective value ciphertext = quadski_pub_key.encrypt( password, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) keys_obj.value = [ciphertext, pem] #start of negotiating session grasp.tprint("Asking for keys") #discover a peer if failct > 3: failct = 0 grasp.tprint("Flushing", keys_obj.name, "discovery") _, ll = grasp.discover(asa_nonce, keys_obj, 1000, flush=True) else: _, ll = grasp.discover(asa_nonce, keys_obj, 1000) if ll == []: grasp.tprint("Discovery failed") failct += 1 return grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate err, snonce, received_obj = grasp.req_negotiate(asa_nonce, keys_obj, ll[0], 5000) if err: if err == grasp.errors.declined and received_obj != "": _e = received_obj else: _e = grasp.etext[err] grasp.tprint("Negotiation error:", _e) failct += 1 grasp.tprint("Fail count", failct) if _e == "Incorrect password": get_pass() return elif (not err) and snonce: grasp.ttprint("requested, session_nonce:", snonce, "received_obj", received_obj) grasp.ttprint("Received raw reply", received_obj.value) grasp.ttprint("received_obj is", received_obj.value) if received_obj.value == b'': grasp.tprint("Keys not found") else: grasp.ttprint("Starting transfer") #decrypt block plaintext = private_key.decrypt( received_obj.value, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) keys = cbor.loads(plaintext) key = keys[0] iv = keys[1] file = open(r"quadsk.py", "w") file.write("key=" + str(key) + "\n") file.write("iv=" + str(iv) + "\n") file.close() grasp.tprint("quadsk.py saved OK") err = grasp.end_negotiate(asa_nonce, snonce, True) if err: grasp.tprint("end_negotiate error:", grasp.etext[err]) else: #immediate end, strange grasp.tprint("Unexpected reply", received_obj.value) #end of a negotiating session time.sleep(10) #pause for something to change... return
def test_rsa_padding_supported_oaep(self): assert backend.rsa_padding_supported( padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None), ) is True
def verify_rsa_signature(signature, signature_scheme, public_key, data): """ <Purpose> Determine whether the corresponding private key of 'public_key' produced 'signature'. verify_signature() will use the public key, signature scheme, and 'data' to complete the verification. >>> public, private = generate_rsa_public_and_private(2048) >>> data = b'The quick brown fox jumps over the lazy dog' >>> scheme = 'rsassa-pss-sha256' >>> signature, scheme = create_rsa_signature(private, data, scheme) >>> verify_rsa_signature(signature, scheme, public, data) True >>> verify_rsa_signature(signature, scheme, public, b'bad_data') False <Arguments> signature: A signature, as a string. This is the signature returned by create_rsa_signature(). signature_scheme: A string that indicates the signature scheme used to generate 'signature'. Currently supported RSA signature schemes are defined in `securesystemslib.keys.RSA_SIGNATURE_SCHEMES`. public_key: The RSA public key, a string in PEM format. data: Data used by securesystemslib.keys.create_signature() to generate 'signature'. 'data' (a string) is needed here to verify 'signature'. <Exceptions> securesystemslib.exceptions.FormatError, if 'signature', 'signature_scheme', 'public_key', or 'data' are improperly formatted. securesystemslib.exceptions.UnsupportedAlgorithmError, if the signature scheme used by 'signature' is not one supported by securesystemslib.keys.create_signature(). securesystemslib.exceptions.CryptoError, if the private key cannot be decoded or its key type is unsupported. <Side Effects> pyca/cryptography's RSAPublicKey.verifier() called to do the actual verification. <Returns> Boolean. True if the signature is valid, False otherwise. """ # Does 'public_key' have the correct format? # This check will ensure 'public_key' conforms to # 'securesystemslib.formats.PEMRSA_SCHEMA'. Raise # 'securesystemslib.exceptions.FormatError' if the check fails. securesystemslib.formats.PEMRSA_SCHEMA.check_match(public_key) # Does 'signature_scheme' have the correct format? securesystemslib.formats.RSA_SCHEME_SCHEMA.check_match(signature_scheme) # Does 'signature' have the correct format? securesystemslib.formats.PYCACRYPTOSIGNATURE_SCHEMA.check_match(signature) # What about 'data'? securesystemslib.formats.DATA_SCHEMA.check_match(data) # Verify whether the private key of 'public_key' produced 'signature'. # Before returning the 'valid_signature' Boolean result, ensure 'RSASSA-PSS' # was used as the signature scheme. valid_signature = False # Verify the RSASSA-PSS signature with pyca/cryptography. try: public_key_object = serialization.load_pem_public_key( public_key.encode('utf-8'), backend=default_backend()) digest_obj = securesystemslib.hash.digest_from_rsa_scheme( signature_scheme, 'pyca_crypto') # verify() raises 'cryptography.exceptions.InvalidSignature' if the # signature is invalid. 'salt_length' is set to the digest size of the # hashing algorithm. try: if signature_scheme.startswith('rsassa-pss'): public_key_object.verify( signature, data, padding.PSS(mgf=padding.MGF1(digest_obj.algorithm), salt_length=digest_obj.algorithm.digest_size), digest_obj.algorithm) elif signature_scheme.startswith('rsa-pkcs1v15'): public_key_object.verify(signature, data, padding.PKCS1v15(), digest_obj.algorithm) # The RSA_SCHEME_SCHEMA.check_match() above should have validated 'scheme'. # This is a defensive check check.. else: # pragma: no cover raise securesystemslib.exceptions.UnsupportedAlgorithmError( 'Unsupported' ' signature scheme is specified: ' + repr(scheme)) return True except cryptography.exceptions.InvalidSignature: return False # Raised by load_pem_public_key(). except (ValueError, cryptography.exceptions.UnsupportedAlgorithm) as e: raise securesystemslib.exceptions.CryptoError( 'The PEM could not be' ' decoded successfully, or contained an unsupported key type: ' + str(e))
def sign(self, confirm=False): url, headers = self.merge_and_headers(self.url) try: check_result = self.simple_check( url, token=headers.get("X-TOKEN"), session=self.session, ) attestation = check_result["attestation"] errored = set(map(lambda x: x[0], check_result["errors"])) key_list = check_result["key_list"] key_hashes = set(map(lambda x: x[0], key_list)) except CheckError as exc: if not exc.key_list or not exc.errored or not exc.attestation: raise exc attestation = exc.attestation errored = set(map(lambda x: x[0], exc.errored)) key_list = exc.key_list key_hashes = set(map(lambda x: x[0], key_list)) if self.hash_key_public not in key_hashes: raise CheckError("Key is not part of chain") if not confirm: return (self.hash_key_public in errored, key_list) # change to update url postbox_update = merge_get_url( replace_action(self.url, "update/"), raw="embed", search="\x1etype=PostBox\x1e", ) # retrieve csrftoken response = self.session.get(postbox_update, headers=headers) graph = Graph() graph.parse(data=response.content, format="html") csrftoken = list(graph.objects(predicate=spkcgraph["csrftoken"]))[ 0 ].toPython() fields = dict( map( lambda x: (x[0].toPython(), x[1].toPython()), graph.query( """ SELECT DISTINCT ?fieldname ?value WHERE { ?base spkc:fieldname ?fieldname ; spkc:value ?value . } """, initNs={"spkc": spkcgraph}, ), ) ) fields["signatures"] = [] own_signature = None for key in self.client_list: if key[0] != self.hash_key_public: signature = key[2] else: # currently only one priv key is supported signature = self.priv_key.sign( attestation, padding.PSS( mgf=padding.MGF1(self.hash_algo), salt_length=padding.PSS.MAX_LENGTH, ), self.hash_algo, ) if signature: fields["signatures"].append( { "hash": f"{self.hash_algo.name}={key[0].hex()}", "signature": "{}={}".format( self.hash_algo.name, base64.b64encode(signature).decode("ascii"), ), } ) if key[0] == self.hash_key_public: own_signature = fields["signatures"][-1]["signature"] fields["signatures"] = json.dumps(fields["signatures"]) # update response = self.session.post( postbox_update, data=fields, headers={"X-CSRFToken": csrftoken, **headers}, ) try: response.raise_for_status() graph = Graph() graph.parse(data=response.content, format="html") vals = set(extract_property(graph, "signature").values()) breakpoint() if own_signature not in vals: raise SrcException("could not update signature", own_signature) except SrcException as exc: raise exc except Exception as exc: raise SrcException( "could not update signature", own_signature ) from exc return (self.hash_key_public in errored, key_list)
def encryption(pubKey, textToEncrypt): #encrypts text with public key cipheredText = pubKey.encrypt(textToEncrypt, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) return cipheredText
def send( self, inp, receivers, headers=b"\n", mode=SendMethod.shared, aes_key=None, ): if not self.ok: raise NotReady() if isinstance(receivers, str): receivers = [receivers] if isinstance(inp, (bytes, memoryview)): inp = io.BytesIO(bytes(inp)) elif isinstance(inp, str): inp = io.BytesIO(inp.encode("utf8")) # 256 bit if not aes_key: aes_key = os.urandom(32) assert len(aes_key) == 32 nonce = os.urandom(13) fencryptor = Cipher( algorithms.AES(aes_key), modes.GCM(nonce), ).encryptor() src_key_list = {} if mode == SendMethod.stealth: pass elif mode == SendMethod.private: enc = self.priv_key.public_key().encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=self.hash_algo), algorithm=self.hash_algo, label=None, ), ) # encrypt decryption key src_key_list[ "%s=%s" % (self.hash_algo.name, self.pub_key_hash) ] = base64.b64encode(enc).decode("ascii") elif mode == SendMethod.shared: for k in self.client_list: enc = k[1].encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=self.hash_algo), algorithm=self.hash_algo, label=None, ), ) # encrypt decryption key src_key_list[ "%s=%s" % (self.hash_algo.name, k[0].hex()) ] = base64.b64encode(enc).decode("ascii") else: raise NotImplementedError() # remove raw as we parse html message_create_url, src_headers = self.merge_and_headers( replace_action(self.component_url, "add/MessageContent/"), raw=None ) response = self.session.get(message_create_url, headers=src_headers) try: response.raise_for_status() except Exception as exc: raise SrcException( "retrieval csrftoken failed", response.text ) from exc g = Graph() g.parse(data=response.content, format="html") csrftoken = list(g.objects(predicate=spkcgraph["csrftoken"]))[0] # create message object response = self.session.post( message_create_url, data={ "own_hash": self.hash_key_public, "key_list": json.dumps(src_key_list), "amount_tokens": len(receivers), }, headers={"X-CSRFToken": csrftoken, **src_headers}, # only for src files={ "encrypted_content": EncryptedFile( fencryptor, inp, nonce, headers ) }, ) try: response.raise_for_status() except Exception as exc: raise SrcException( "Message creation failed", response.text ) from exc if message_create_url == response.url: raise SrcException("Message creation failed", response.text) g = Graph() g.parse(data=response.content, format="html") fetch_url = list( map( lambda x: x.value, g.query( """ SELECT ?value WHERE { ?property spkc:name ?name ; spkc:value ?value . } """, initNs={"spkc": spkcgraph}, initBindings={ "name": Literal("fetch_url", datatype=XSD.string) }, ), ) ) tokens = list( map( lambda x: x.value, g.query( """ SELECT ?value WHERE { ?property spkc:name ?name ; spkc:value ?value . } """, initNs={"spkc": spkcgraph}, initBindings={ "name": Literal("tokens", datatype=XSD.string) }, ), ) ) if not fetch_url or not tokens: raise SrcException("Message creation failed", response.text) fetch_url = fetch_url[0].toPython() exceptions = [] final_fetch_urls = [] for receiver, token in zip(receivers, tokens): furl = merge_get_url(fetch_url, token=token.toPython()) try: self._send_dest(aes_key, furl, receiver) final_fetch_urls.append(furl) except Exception as exc: exceptions.append(exc) # for autoremoval simulate access self.session.get(furl) return exceptions, final_fetch_urls, aes_key
def receive( self, message_id, outfp=None, access_method=AccessMethod.view, extra_key_hashes=None, max_size=None, ): if not self.ok: raise NotReady() merged_url, headers = self.merge_and_headers(self.url, raw="embed") response = self.session.get( merge_get_url(self.url, raw="embed"), headers=headers ) response.raise_for_status() graph = Graph() graph.parse(data=response.content, format="turtle") self.retrieve_missing(graph, merged_url) result = list( graph.query( """ SELECT DISTINCT ?base ?hash_algorithm ?type WHERE { ?base a <https://spkcspider.net/static/schemes/spkcgraph#spkc:Content> ; spkc:type ?type ; spkc:properties ?propalg , ?propid . ?propid spkc:name ?idname ; spkc:value ?idvalue . ?propalg spkc:name ?algname ; spkc:value ?hash_algorithm . } """, # noqa E501 initNs={"spkc": spkcgraph}, initBindings={ "idvalue": Literal(message_id), "algname": Literal("hash_algorithm", datatype=XSD.string), "idname": Literal("id", datatype=XSD.string), }, ) ) if not result or result[0].type.toPython() not in { "WebReference", "MessageContent", }: raise SrcException("No Message") # every object has it's own copy of the hash algorithm, used hash_algo = getattr(hashes, result[0].hash_algorithm.upper())() if not outfp: outfp = tempfile.TempFile() if hash_algo == self.hash_algo: pub_key_hashalg = "%s=%s" % ( hash_algo.name, self.hash_key_public.hex(), ) else: digest = hashes.Hash(hash_algo) digest.update(self.pem_key_public) pub_key_hashalg = "%s=%s" % ( hash_algo.name, digest.finalize().hex(), ) key_hashes = list() if extra_key_hashes: extra_key_hashes = set(extra_key_hashes) extra_key_hashes.discard(pub_key_hashalg) for key in self.client_list: if key[0] in extra_key_hashes: if hash_algo == self.hash_algo: key_hashalg = "%s=%s" % (hash_algo.name, key[0]) else: digest = hashes.Hash(hash_algo) digest.update(key[1]) key_hashalg = "%s=%s" % ( hash_algo.name, digest.finalize().hex(), ) key_hashes.append(key_hashalg) if access_method == AccessMethod.view: key_hashes.append(pub_key_hashalg) retrieve_url, headers = self.merge_and_headers( replace_action( result[0].base, "bypass/" if (access_method == AccessMethod.bypass) else "message/", ) ) data = {} if access_method != AccessMethod.bypass: data.update({"max_size": max_size or "", "keyhash": key_hashes}) response = self.session.post( retrieve_url, stream=True, headers=headers, data=data ) try: response.raise_for_status() except Exception as exc: raise DestException( "Message retrieval failed", response.text ) from exc key_list = json.loads(response.headers["X-KEYLIST"]) key = key_list.get(pub_key_hashalg, None) if not key: raise WrongRecipient("message not for me") decrypted_key = self.priv_key.decrypt( base64.b64decode(key), padding.OAEP( mgf=padding.MGF1(algorithm=hash_algo), algorithm=hash_algo, label=None, ), ) headblock = b"" fdecryptor = None eparser = emailparser.BytesFeedParser(policy=policy.default) headers = None for chunk in response.iter_content(chunk_size=256): blob = None if not fdecryptor: headblock = b"%b%b" % (headblock, chunk) if b"\0" in headblock: nonce, headblock = headblock.split(b"\0", 1) nonce = base64.b64decode(nonce) fdecryptor = Cipher( algorithms.AES(decrypted_key), modes.GCM(nonce), ).decryptor() blob = fdecryptor.update(headblock[:-16]) headblock = headblock[-16:] else: continue else: blob = fdecryptor.update(b"%b%b" % (headblock, chunk[:-16])) headblock = chunk[-16:] if not headers: if b"\n\n" not in blob: eparser.feed(blob) continue headersrest, blob = blob.split(b"\n\n", 1) eparser.feed(headersrest) headers = eparser.close() # check what to do t = headers.get("SPKC-Type", MessageType.email) if t == MessageType.email: outfp.write( headers.as_bytes(unixfrom=True, policy=policy.SMTP) ) outfp.write(blob) outfp.write(fdecryptor.finalize_with_tag(headblock)) return outfp, headers, decrypted_key
def _send_dest(self, aes_key, fetch_url, dest): dest_url = merge_get_url( dest, raw="embed", search="\x1etype=PostBox\x1e" ) response_dest = self.session.get(dest_url, timeout=60) try: response_dest.raise_for_status() g_dest = Graph() g_dest.parse(data=response_dest.content, format="turtle") self.retrieve_missing(g_dest, dest_url) except Exception as exc: raise DestException("postbox retrieval failed") from exc dest_postboxes = get_postboxes(g_dest) if len(dest_postboxes) != 1: raise DestException("No postbox found/more than one found") dest_postbox_url, dest_options = next(iter(dest_postboxes.items())) webref_url = replace_action(dest_postbox_url, "push_webref/") attestation = dest_options["attestation"] bdomain = dest_postbox_url.split("?", 1)[0] result_dest, errors, dest_keys = self.attestation_checker.check( bdomain, map( lambda x: (x["key"], x["signature"]), dest_options["signatures"].values(), ), attestation=attestation, algo=dest_options["hash_algorithm"], auto_add=True, ) if result_dest == AttestationResult.domain_unknown: logger.info("add domain: %s", bdomain) self.attestation_checker.attestation.add( bdomain, dest_keys, algo=dest_options["hash_algorithm"], embed=True, ) elif result_dest == AttestationResult.error: if len(dest_keys) == 0: raise DestException("No keys found") raise DestSecurityException("dest contains invalid keys", errors) dest_key_list = {} for k in dest_keys: enc = k[1].encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=dest_options["hash_algorithm"]), algorithm=dest_options["hash_algorithm"], label=None, ), ) # encrypt decryption key dest_key_list[ "%s=%s" % (dest_options["hash_algorithm"].name, k[0].hex()) ] = base64.b64encode(enc).decode("ascii") try: response_dest = self.session.post( webref_url, data={"url": fetch_url, "key_list": json.dumps(dest_key_list)}, timeout=60, ) response_dest.raise_for_status() except Exception as exc: raise DestException("post webref failed") from exc
# private_key = serialization.load_pem_private_key( # key_file.read(), # password = None, # backend = default_backend() # ) # Public Key public_key = private_key.public_key() # Encryption to ciphertext (requires a public key) # The message1 variable holds the initial message (in bits) before encryption message1 = b"Test Message" ciphertext = public_key.encrypt( message1, padding.OAEP( mgf = padding.MGF1(algorithm = hashes.SHA1()), algorithm = hashes.SHA1(), label = None ) ) # Test print the encrypted ciphertest print("\nEncrypted! Ciphertext is:\n{}".format(ciphertext)) # Signing, padding, and salt signature = private_key.sign( message1, padding.PSS( mgf = padding.MGF1(hashes.SHA256()), salt_length = padding.PSS.MAX_LENGTH ),
def sign(message): signature = private_key.sign( message, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) return signature
def test_rsa_padding_unsupported_pss_mgf1_hash(self): assert backend.rsa_padding_supported( padding.PSS(mgf=padding.MGF1(DummyHashAlgorithm()), salt_length=0)) is False
def decryption(privKey, cipheredText): #decrypts encrypted text with private key noCipheredText = privKey.decrypt(cipheredText, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) return noCipheredText
def test_rsa_padding_supported_pss(self): assert backend.rsa_padding_supported( padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0)) is True
def action_view(argv, priv_key, pem_public, own_url, session, g_message): if argv.message_id is not None: assert isinstance(argv.message_id, int) result = list(g_message.query( """ SELECT DISTINCT ?base ?hash_algorithm ?type WHERE { ?base a <https://spkcspider.net/static/schemes/spkcgraph#spkc:Content> ; spkc:type ?type ; spkc:properties ?propalg , ?propid . ?propid spkc:name ?idname ; spkc:value ?idvalue . ?propalg spkc:name ?algname ; spkc:value ?hash_algorithm . } """, # noqa E501 initNs={"spkc": spkcgraph}, initBindings={ "idvalue": Literal(argv.message_id), "algname": Literal( "hash_algorithm", datatype=XSD.string ), "idname": Literal( "id", datatype=XSD.string ), } )) if not result or result[0].type.toPython() not in { "WebReference", "MessageContent" }: parser.exit(0, "message not found\n") pub_key_hasher = getattr( hashes, result[0].hash_algorithm.upper() )() digest = hashes.Hash(pub_key_hasher, backend=default_backend()) digest.update(pem_public) pub_key_hashalg = "%s=%s" % ( pub_key_hasher.name, digest.finalize().hex() ) retrieve_url = merge_get_url( replace_action( result[0].base, "message/" ) ) data = { "max_size": argv.max } if argv.action == "view": data["keyhash"] = pub_key_hashalg response = session.post( retrieve_url, stream=True, headers={ "X-TOKEN": argv.token }, data=data ) if not response.ok: logger.info("Message retrieval failed: %s", response.text) parser.exit(0, "message could not be fetched\n") key_list = json.loads(response.headers["X-KEYLIST"]) key = key_list.get(pub_key_hashalg, None) if not key: parser.exit(0, "message not for me\n") decrypted_key = priv_key.decrypt( base64.b64decode(key), padding.OAEP( mgf=padding.MGF1(algorithm=argv.src_hash_algo), algorithm=argv.src_hash_algo, label=None ) ) headblock = b"" fdecryptor = None eparser = emailparser.BytesFeedParser(policy=policy.default) headers = None for chunk in response.iter_content(chunk_size=256): blob = None if not fdecryptor: headblock = b"%b%b" % (headblock, chunk) if b"\0" in headblock: nonce, headblock = headblock.split(b"\0", 1) nonce = base64.b64decode(nonce) fdecryptor = Cipher( algorithms.AES(decrypted_key), modes.GCM(nonce), backend=default_backend() ).decryptor() blob = fdecryptor.update(headblock[:-16]) headblock = headblock[-16:] else: continue else: blob = fdecryptor.update( b"%b%b" % (headblock, chunk[:-16]) ) headblock = chunk[-16:] if not headers: if b"\n\n" not in blob: eparser.feed(blob) continue headersrest, blob = blob.split(b"\n\n", 1) eparser.feed(headersrest) headers = eparser.close() # check what to do t = headers.get("SPKC-Type", MessageType.email) if t == MessageType.email: argv.file.write(headers.as_bytes( unixfrom=True, policy=policy.SMTP )) argv.file.write(blob) argv.file.write(fdecryptor.finalize_with_tag(headblock)) else: queried_webrefs = {} queried_messages = {} for i in g_message.query( """ SELECT DISTINCT ?base ?idvalue ?namevalue ?type WHERE { ?base a <https://spkcspider.net/static/schemes/spkcgraph#spkc:Content> ; spkc:type ?type ; spkc:properties ?propname , ?propid . ?propid spkc:name ?idname ; spkc:value ?idvalue . ?propname spkc:name ?namename ; spkc:value ?namevalue . } """, # noqa E501 initNs={"spkc": spkcgraph}, initBindings={ "idname": Literal( "id", datatype=XSD.string ), "namename": Literal( "name", datatype=XSD.string ), } ): if i.type.toPython() == "WebReference": queried = queried_webrefs elif i.type.toPython() == "MessageContent": queried = queried_messages else: continue queried.setdefault(str(i.base), {}) queried[str(i.base)]["id"] = i.idvalue queried[str(i.base)]["name"] = i.namevalue print("Received Messages:") for i in sorted(queried_webrefs.values(), key=lambda x: x["id"]): print(i["id"], i["name"]) print("Own Messages:") for i in sorted(queried_messages.values(), key=lambda x: x["id"]): print(i["id"], i["name"])
def create_rsa_signature(private_key, data, scheme='rsassa-pss-sha256'): """ <Purpose> Generate a 'scheme' signature. The signature, and the signature scheme used, is returned as a (signature, scheme) tuple. The signing process will use 'private_key' to generate the signature of 'data'. RFC3447 - RSASSA-PSS http://www.ietf.org/rfc/rfc3447.txt >>> public, private = generate_rsa_public_and_private(2048) >>> data = 'The quick brown fox jumps over the lazy dog'.encode('utf-8') >>> scheme = 'rsassa-pss-sha256' >>> signature, scheme = create_rsa_signature(private, data, scheme) >>> securesystemslib.formats.NAME_SCHEMA.matches(scheme) True >>> scheme == 'rsassa-pss-sha256' True >>> securesystemslib.formats.PYCACRYPTOSIGNATURE_SCHEMA.matches(signature) True <Arguments> private_key: The private RSA key, a string in PEM format. data: Data (string) used by create_rsa_signature() to generate the signature. scheme: The signature scheme used to generate the signature. <Exceptions> securesystemslib.exceptions.FormatError, if 'private_key' is improperly formatted. ValueError, if 'private_key' is unset. securesystemslib.exceptions.CryptoError, if the signature cannot be generated. <Side Effects> pyca/cryptography's 'RSAPrivateKey.signer()' called to generate the signature. <Returns> A (signature, scheme) tuple, where the signature is a string and the scheme is one of the supported RSA signature schemes. For example: 'rsassa-pss-sha256'. """ # Does the arguments have the correct format? # If not, raise 'securesystemslib.exceptions.FormatError' if any of the # checks fail. securesystemslib.formats.PEMRSA_SCHEMA.check_match(private_key) securesystemslib.formats.DATA_SCHEMA.check_match(data) securesystemslib.formats.RSA_SCHEME_SCHEMA.check_match(scheme) # Signing 'data' requires a private key. Currently supported RSA signature # schemes are defined in `securesystemslib.keys.RSA_SIGNATURE_SCHEMES`. signature = None # Verify the signature, but only if the private key has been set. The # private key is a NULL string if unset. Although it may be clearer to # explicitly check that 'private_key' is not '', we can/should check for a # value and not compare identities with the 'is' keyword. Up to this point # 'private_key' has variable size and can be an empty string. if not len(private_key): raise ValueError('The required private key is unset.') try: # 'private_key' (in PEM format) must first be converted to a # pyca/cryptography private key object before a signature can be # generated. private_key_object = load_pem_private_key(private_key.encode('utf-8'), password=None, backend=default_backend()) digest_obj = securesystemslib.hash.digest_from_rsa_scheme( scheme, 'pyca_crypto') if scheme.startswith('rsassa-pss'): # Generate an RSSA-PSS signature. Raise # 'securesystemslib.exceptions.CryptoError' for any of the expected # exceptions raised by pyca/cryptography. signature = private_key_object.sign( data, padding.PSS(mgf=padding.MGF1(digest_obj.algorithm), salt_length=digest_obj.algorithm.digest_size), digest_obj.algorithm) elif scheme.startswith('rsa-pkcs1v15'): # Generate an RSA-PKCS1v15 signature. Raise # 'securesystemslib.exceptions.CryptoError' for any of the expected # exceptions raised by pyca/cryptography. signature = private_key_object.sign(data, padding.PKCS1v15(), digest_obj.algorithm) # The RSA_SCHEME_SCHEMA.check_match() above should have validated 'scheme'. # This is a defensive check check.. else: # pragma: no cover raise securesystemslib.exceptions.UnsupportedAlgorithmError( 'Unsupported' ' signature scheme is specified: ' + repr(scheme)) # If the PEM data could not be decrypted, or if its structure could not # be decoded successfully. except ValueError: raise securesystemslib.exceptions.CryptoError( 'The private key' ' (in PEM format) could not be deserialized.') # 'TypeError' is raised if a password was given and the private key was # not encrypted, or if the key was encrypted but no password was # supplied. Note: A passphrase or password is not used when generating # 'private_key', since it should not be encrypted. except TypeError: raise securesystemslib.exceptions.CryptoError( 'The private key was' ' unexpectedly encrypted.') # 'cryptography.exceptions.UnsupportedAlgorithm' is raised if the # serialized key is of a type that is not supported by the backend, or if # the key is encrypted with a symmetric cipher that is not supported by # the backend. except cryptography.exceptions.UnsupportedAlgorithm: # pragma: no cover raise securesystemslib.exceptions.CryptoError( 'The private key is' ' encrypted with an unsupported algorithm.') return signature, scheme
def action_check(argv, priv_key, pub_key_hash, session, g): src = {} postbox = None for i in g.query( """ SELECT DISTINCT ?postbox ?key_base ?key_base_prop ?key_name ?key_value WHERE { ?postbox spkc:properties ?postbox_prop . ?postbox_prop spkc:name ?postbox_prop_name . ?postbox_prop spkc:value ?key_base . ?key_base spkc:properties ?key_base_prop . ?key_base_prop spkc:name ?key_name ; spkc:value ?key_value . } """, initNs={"spkc": spkcgraph}, initBindings={ "postbox_prop_name": Literal( "signatures", datatype=XSD.string ) } ): postbox = i.postbox src.setdefault(str(i.key_base), {}) src[str(i.key_base)][str(i.key_name)] = i.key_value src_activator_value, errored, key_list = argv.attestation.check_signatures( map( lambda x: (x["key"], x["signature"]), src.values() ), algo=argv.src_hash_algo ) tmp = list(g.query( """ SELECT DISTINCT ?value WHERE { ?base spkc:name ?name . ?base spkc:value ?value . } """, initNs={"spkc": spkcgraph}, initBindings={ "name": Literal( "attestation", datatype=XSD.string ), } )) if tmp[0][0].toPython() != src_activator_value: return "activator doesn't match shown activator" if errored: pub_key_hash_bin = bytes.fromhex(pub_key_hash) can_fix = set(filter( lambda x: x == pub_key_hash_bin, map(lambda x: x[0], errored) )) if not argv.fix: if can_fix and postbox: print("Can fix signature") else: if not can_fix or not postbox: return ", ".join(map(lambda x: x.hex(), errored)) postbox_update = replace_action( postbox, "update/" ) # retrieve token response = session.get( postbox_update, headers={ "X-TOKEN": argv.token } ) g_token = Graph() g_token.parse(data=response.content, format="html") csrftoken = list(g_token.objects( predicate=spkcgraph["csrftoken"]) )[0].toPython() fields = dict(map( lambda x: (x[0].toPython(), x[1].toPython()), g_token.query( """ SELECT DISTINCT ?fieldname ?value WHERE { ?base spkc:fieldname ?fieldname . ?base spkc:value ?value . } """, initNs={"spkc": spkcgraph}, ) )) fields["signatures"] = [] for key in key_list: if key[0] not in can_fix: signature = key[2] else: # currently only one priv key is supported signature = priv_key.sign( src_activator_value, padding.PSS( mgf=padding.MGF1(argv.src_hash_algo), salt_length=padding.PSS.MAX_LENGTH ), argv.src_hash_algo ) if signature: fields["signatures"].append( { "hash": f"{argv.src_hash_algo.name}={key[0].hex()}", "signature": "{}={}".format( argv.src_hash_algo.name, base64.b64encode( signature ).decode("ascii") ) } ) fields["signatures"] = json.dumps(fields["signatures"]) # update response = session.post( postbox_update, data=fields, headers={ "X-CSRFToken": csrftoken, "X-TOKEN": argv.token } ) if not response.ok: logger.error("Repair failed: %s", response.text) return ", ".join(map(lambda x: x[0].hex(), errored)) logger.info("Repair succeeded") errored = list(filter(lambda x: x not in can_fix, errored)) if errored == 0: return True return ", ".join(map(lambda x: x[0].hex(), errored)) return True
def sign(self, msg, key): return key.sign( msg, padding.PSS(mgf=padding.MGF1(self.hash_alg()), salt_length=self.hash_alg.digest_size), self.hash_alg())
def action_send(argv, priv_key, pub_key_hash, src_keys, session, g_src): postboxes = get_postboxes(g_src) if len(postboxes) != 1: parser.exit(1, "Source cannot create messages, logged in?") component_uriref, src_options = next(postboxes.items()) dest_url = merge_get_url( argv.dest, raw="embed", search="\x1etype=PostBox\x1e" ) response_dest = session.get(dest_url) if not response_dest.ok: logger.info("Dest returned error: %s", response_dest.text) parser.exit(1, "retrieval failed, invalid url?\n") g_dest = Graph() g_dest.parse(data=response_dest.content, format="turtle") for page in get_pages(g_dest)[1]: with session.get( merge_get_url(dest_url, page=page) ) as response: response.raise_for_status() g_dest.parse(data=response.content, format="turtle") dest_postboxes = get_postboxes(g_dest) if len(dest_postboxes) != 1: parser.exit(1, "Dest has no/too many postboxes") dest_postbox_url, dest_options = next(dest_postboxes.items()) webref_url = replace_action(dest_postbox_url, "push_webref/") dest_hash_algo = dest_options["hash_algorithm"] attestation = dest_options["attestation"] bdomain = dest_postbox_url.split("?", 1)[0] result_dest, _, dest_keys = argv.attestation.check( bdomain, map( lambda x: (x["key"], x["signature"]), dest_options["signatures"].values() ), attestation=attestation, algo=dest_hash_algo ) if result_dest == AttestationResult.domain_unknown: logger.info("add domain: %s", bdomain) argv.attestation.add( bdomain, dest_keys, algo=dest_hash_algo ) elif result_dest == AttestationResult.error: logger.critical("Dest base url contains invalid keys.") parser.exit(1, "dest contains invalid keys\n") # 256 bit aes_key = os.urandom(32) nonce = os.urandom(13) fencryptor = Cipher( algorithms.AES(aes_key), modes.GCM(nonce), backend=default_backend() ).encryptor() src_key_list = {} dest_key_list = {} if argv.stealth: pass elif src_options["shared"]: for k in src_keys: enc = k[1].encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=argv.src_hash_algo), algorithm=argv.src_hash_algo, label=None ) ) # encrypt decryption key src_key_list[ "%s=%s" % (argv.src_hash_algo.name, k[0].hex()) ] = base64.b64encode(enc).decode("ascii") else: enc = priv_key.public_key().encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=argv.src_hash_algo), algorithm=argv.src_hash_algo, label=None ) ) # encrypt decryption key src_key_list[ "%s=%s" % (argv.src_hash_algo.name, pub_key_hash) ] = base64.b64encode(enc).decode("ascii") for k in dest_keys: enc = k[1].encrypt( aes_key, padding.OAEP( mgf=padding.MGF1(algorithm=dest_hash_algo), algorithm=dest_hash_algo, label=None ) ) # encrypt decryption key dest_key_list[ "%s=%s" % (dest_hash_algo.name, k[0].hex()) ] = base64.b64encode(enc).decode("ascii") headers = b"SPKC-Type: %b\n" % MessageType.file # remove raw as we parse html message_create_url = merge_get_url( replace_action(str(component_uriref), "add/MessageContent/"), raw=None ) response = session.get( message_create_url, headers={ "X-TOKEN": argv.token } ) if not response.ok: logger.error("retrieval csrftoken failed: %s", response.text) parser.exit(1, "retrieval csrftoken failed: %s" % response.text) g = Graph() g.parse(data=response.content, format="html") csrftoken = list(g.objects(predicate=spkcgraph["csrftoken"]))[0] # create message object response = session.post( message_create_url, data={ "own_hash": pub_key_hash, "key_list": json.dumps(src_key_list), "amount_tokens": 1 }, headers={ "X-CSRFToken": csrftoken, "X-TOKEN": argv.token # only for src }, files={ "encrypted_content": EncryptedFile( fencryptor, argv.file, nonce, headers ) } ) if not response.ok or message_create_url == response.url: logger.error("Message creation failed: %s", response.text) parser.exit(1, "Message creation failed: %s" % response.text) g = Graph() g.parse(data=response.content, format="html") fetch_url = list(map(lambda x: x.value, g.query( """ SELECT ?value WHERE { ?property spkc:name ?name ; spkc:value ?value . } """, initNs={"spkc": spkcgraph}, initBindings={ "name": Literal( "fetch_url", datatype=XSD.string ) } ))) tokens = list(map(lambda x: x.value, g.query( """ SELECT ?value WHERE { ?property spkc:name ?name ; spkc:value ?value . } """, initNs={"spkc": spkcgraph}, initBindings={ "name": Literal( "tokens", datatype=XSD.string ) } ))) if not fetch_url or not tokens: logger.error("Message creation failed: %s", response.text) parser.exit(1, "Message creation failed") # extract url response_dest = session.post( webref_url, data={ "url": merge_get_url(fetch_url[0], token=str(tokens[0])), "key_list": json.dumps(dest_key_list) } ) if not response_dest.ok: logger.error("Sending message failed: %s", response_dest.text) parser.exit(1, "Sending message failed")
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding with open("E:\\Assignment\\public_key.pem", "rb") as key_file_2: public_key = serialization.load_pem_public_key(key_file_2.read(), backend=default_backend()) with open("E:\\Assignment\\Message.txt", "rb") as M: message = M.read() print(message) encrypted = public_key.encrypt( message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) with open('E:\\Assignment\\Message.encrypted', 'wb') as f: f.write(encrypted)
def __init__(self, name, hash_): super(_JWAPS, self).__init__(name) self.padding = padding.PSS(mgf=padding.MGF1(hash_()), salt_length=padding.PSS.MAX_LENGTH) self.hash = hash_()
def _pss_padding(cls, algorithm): padding_data = padding.PSS( mgf=padding.MGF1(algorithm), salt_length=padding.PSS.MAX_LENGTH ) return padding_data
def crap_handshake_recv(self, packet): if(self.status_crap == "ESTABLISTHED"): logger.debug("the connection has been established") return if self.mode == "server" and packet.status == 0: our_cert_temp = open('team5_signed.cert', 'rb').read() # to do our cert our_private_key_temp = open('private_key.pem', 'rb').read() self.our_cert_final = x509.load_pem_x509_certificate(our_cert_temp, default_backend()) self.our_private_key_final = load_pem_private_key(our_private_key_temp,password=None,backend=default_backend()) certification = x509.load_pem_x509_certificate(packet.cert, default_backend()) self.get_pubKA = certification.public_key() # print(self.get_pubKA.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)) try: logger.debug("the server sends back handshake") self.get_pubKA.verify(packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) our_addr = self.our_cert_final.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value receive_addr = certification.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value print("Team address:", our_addr) print("Client address:", receive_addr) if our_addr in receive_addr: print("Verify success") pass else: raise except Exception as error: logger.debug("wrong signature") new_secure_packet = HandshakePacket(status=2) self.transport.write(new_secure_packet.__serialize__()) self.transport.close() # Create Server long term key print("good") self.privatekeyB = ec.generate_private_key(ec.SECP384R1(), default_backend()) pubkB = self.privatekeyB.public_key() print("good2") # serialization tmp_pubkB = pubkB.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo) self.datasentB = tmp_pubkB # Create ephemeral key for signing self.signaturekB = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) self.pubk_sign_B = self.signaturekB.public_key() # Create signature sign_B = self.signaturekB.sign(self.datasentB, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) # Create nonceB tmp_nonceB = randrange(2**32) self.nonceB = str(tmp_nonceB).encode('ASCII') # Reveive nonceA nonceA = str(packet.nonce).encode('ASCII') # Generate shared key pubkB_recv = load_pem_public_key(packet.pk, backend=default_backend()) self.server_shared_key = self.privatekeyB.exchange(ec.ECDH(), pubkB_recv) print("generating ") # Create certificate with the help of ephemeral private key subject = issuer = x509.Name([ x509.NameAttribute(NameOID.COUNTRY_NAME, u"CN"), x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"MarryLand"), x509.NameAttribute(NameOID.LOCALITY_NAME, u"Peskvile"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Team 5"), x509.NameAttribute(NameOID.COMMON_NAME, u"20194.5.5.5"), ]) certificate = x509.CertificateBuilder().subject_name( subject ).issuer_name( self.our_cert_final.subject ).public_key( self.signaturekB.public_key() ).serial_number( x509.random_serial_number() ).not_valid_before( datetime.datetime.utcnow() ).not_valid_after( # Our certificate will be valid for 10 days datetime.datetime.utcnow() + datetime.timedelta(days=10) ).add_extension( x509.SubjectAlternativeName([x509.DNSName(u"localhost")]), critical=False, # Sign our certificate with our private key ).sign(self.our_private_key_final, hashes.SHA256(), default_backend()) # Create CertB to transmit (serialization) certB = certificate.public_bytes(Encoding.PEM) #create certChain self.chainB = [our_cert_temp] # Create nonceSignatureB (bytes) nonceSignatureB = self.signaturekB.sign(nonceA, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) new_secure_packet = HandshakePacket(status=1, pk=self.datasentB, signature=sign_B, nonce=tmp_nonceB, nonceSignature=nonceSignatureB, cert=certB) self.transport.write(new_secure_packet.__serialize__()) elif self.mode == "server" and packet.status == 1: try: self.get_pubKA.verify(packet.nonceSignature, self.nonceB, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) except Exception as error: logger.debug("Server verify failed because wrong signature") new_secure_packet = HandshakePacket(status=2) self.transport.write(new_secure_packet.__serialize__()) self.transport.close() print("Handshake complete") #Generating the hash digest1_temp = hashes.Hash(hashes.SHA256(),backend = default_backend()) digest1_temp.update(self.server_shared_key) hash1 = digest1_temp.finalize() self.IVA = hash1[0:12] self.IVB = hash1[12:24] print("server's IVA =",self.IVA) print("server's IVB =",self.IVB) digest2_temp = hashes.Hash(hashes.SHA256(),backend = default_backend()) digest2_temp.update(hash1) hash2 = digest2_temp.finalize() self.decB = hash2[0:16] print("server's dec:",self.decB) digest3_temp = hashes.Hash(hashes.SHA256(),backend = default_backend()) digest3_temp.update(hash2) hash3 = digest3_temp.finalize() self.encB = hash3[0:16] print("server's dec:", self.encB) self.status_crap = "ESTABLISHED" self.higherProtocol().connection_made(self.higher_transport) if self.mode == "client" and packet.status == 1: certification = x509.load_pem_x509_certificate(packet.cert, default_backend()) extract_pubkB = certification.public_key() try: extract_pubkB.verify(packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) extract_pubkB.verify(packet.nonceSignature, self.nonceA, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) our_addr = self.our_cert_final.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value receive_addr = certification.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value print("Team address:", our_addr) print("Client address:", receive_addr) if our_addr in receive_addr: print("Verify success") pass else: raise except Exception as error: logger.debug("client verify failed because wrong signature") new_secure_packet = HandshakePacket(status=2) self.transport.write(new_secure_packet.__serialize__()) self.transport.close() # Generate shared key pubkA_recv = load_pem_public_key(packet.pk, backend=default_backend()) print(pubkA_recv) print(self.privatekeyB) client_shared_key = self.privatekeyB.exchange(ec.ECDH(), pubkA_recv) # Reveive nonceB nonceB = str(packet.nonce).encode('ASCII') nonceSignatureA = self.signaturekA.sign(nonceB, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) new_secure_packet = HandshakePacket(status=1, nonceSignature=nonceSignatureA) self.transport.write(new_secure_packet.__serialize__()) print("The third handshake has been established") # Generating the hash digest1_temp = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest1_temp.update(self.server_shared_key) hash1 = digest1_temp.finalize() self.IVA = hash1[0:12] self.IVB = hash1[12:24] print("server's IVA =", self.IVA) print("server's IVB =", self.IVB) digest2_temp = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest2_temp.update(hash1) hash2 = digest2_temp.finalize() self.decB = hash2[0:16] print("server's dec:", self.decB) digest3_temp = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest3_temp.update(hash2) hash3 = digest3_temp.finalize() self.encB = hash3[0:16] print("server's dec:", self.encB) self.status_crap = "ESTABLISHED" self.higherProtocol().connection_made(self.higher_transport)
def take_ownership(self, ownerpass_digest, srkpass_digest, pubek): """ Run TPM_TakeOwernship """ exponent = int('10001', 16) modulus = int(pubek.hex(), 16) pubekkey = RSAPublicNumbers( exponent, modulus).public_key(backend=default_backend()) oaep = padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label="TCPA".encode()) enc_owner_auth = pubekkey.encrypt(ownerpass_digest, oaep) enc_srk_auth = pubekkey.encrypt(srkpass_digest, oaep) nonce_even, auth_handle, ret = self.oiap() if ret != 0: return 1 tpm_rsa_key_parms = struct.pack( ">III", 2048, # keyLength 2, # numPrimes 0) # exponentSize tpm_key_parms = struct.pack( ">I HH I%ds" % (len(tpm_rsa_key_parms)), TPM_ALG_RSA, # algorithmId TPM_ES_RSAESOAEP_SHA1_MGF1, # encScheme TPM_SS_NONE, # sigScheme len(tpm_rsa_key_parms), tpm_rsa_key_parms) tpm_key12 = struct.pack( ">HH HIB %ds I I I" % (len(tpm_key_parms)), TPM_TAG_KEY12, 0, TPM_KEY_STORAGE, # keyUsage 0, # keyFlags TPM_AUTH_ALWAYS, # authDataUsage tpm_key_parms, 0, 0, 0) fmt_auth = ">I20sB20s" fmt = ">HII H I256s I256s %ds" % len(tpm_key12) nonce_odd = os.urandom(20) req = struct.pack(fmt, TPM_TAG_RQU_AUTH1_COMMAND, struct.calcsize(fmt) + struct.calcsize(fmt_auth), TPM_ORD_TAKE_OWNERSHIP, TPM_PID_OWNER, len(enc_owner_auth), enc_owner_auth, len(enc_srk_auth), enc_srk_auth, tpm_key12) # req needs authhandle, nonceodd & ownerAuth appended shainput = struct.unpack("%ds" % (len(req) - 6), req[6:len(req)])[0] in_param_digest = sha1(shainput) continue_auth_session = 0 in_auth_setup_params = struct.pack(">20s20sB", nonce_even, nonce_odd, continue_auth_session) macinput = struct.pack(">20s %ds" % len(in_auth_setup_params), in_param_digest, in_auth_setup_params) myhmac = hmac.HMAC(ownerpass_digest, hashes.SHA1(), backend=default_backend()) myhmac.update(macinput) owner_auth = myhmac.finalize() req += struct.pack(fmt_auth, auth_handle, nonce_odd, continue_auth_session, owner_auth) _, ret = self.transfer(req, "TPM_TakeOwnership") return ret
def connection_made(self, transport): logger.debug("{} Crap: connection made".format(self.mode)) self.transport = transport print(333333333333333333333333333333333) self.higher_transport = CRAPTransport(transport) self.higher_transport.connect_protocol(self) print("Crap:connection_made") print(self.mode) if self.mode == "client": # Using print(1111111111111111111111111) self.privatekeyA = ec.generate_private_key(ec.SECP384R1(), default_backend()) pubkA = self.privatekeyA.public_key() #save original pubkA publickA = pubkA print(222222222222222222222222) # Create pk in packet (serialization) pubkA = pubkA.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo) self.datasentA = pubkA # Create long term key for signing self.signaturekA = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) self.pubk_sign_A = self.signaturekA.public_key() print(555555) # Create signature sign_A = self.signaturekA.sign(self.datasentA, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) # Create nonceA nonceA = randrange(2**32) self.nonceA = str(nonceA).encode('ASCII') print(66666) #load our certificate our_cert_temp = open('team5_signed.cert','rb').read()# to do our cert print(77777) our_private_key_temp = open('private_key.pem','rb').read() self.our_cert_final = x509.load_pem_x509_certificate(our_cert_temp,default_backend()) print(231323131) self.our_private_key_final = load_pem_private_key(our_private_key_temp,password=None,backend=default_backend()) print("ssssssssssssssssssssswqeqweqwe") print(213112331233) # Create certificate with the help of ephemeral private key subject = issuer = x509.Name([ x509.NameAttribute(NameOID.COUNTRY_NAME, u"CN"), x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"MarryLand"), x509.NameAttribute(NameOID.LOCALITY_NAME, u"Baltimore"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Team 5"), x509.NameAttribute(NameOID.COMMON_NAME, u"20194.5.5.5"), ]) certificate = x509.CertificateBuilder().subject_name( subject ).issuer_name( self.our_cert_final.subject #change the issuer of the cert ).public_key( self.signaturekA.public_key() ).serial_number( x509.random_serial_number() ).not_valid_before( datetime.datetime.utcnow() ).not_valid_after( # Our certificate will be valid for 10 days datetime.datetime.utcnow() + datetime.timedelta(days=10) ).add_extension( x509.SubjectAlternativeName([x509.DNSName(u"20194.5.5.5")]), critical=False, # Sign our certificate with our private key ).sign(self.our_private_key_final, hashes.SHA256(), default_backend()) print("certificate generate") # Create CertA to transmit (serialization) certA = certificate.public_bytes(Encoding.PEM) #print(self.pubk_sign_A.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)) #Create the cert chain self.chainA = [our_cert_temp] print(self.chainA) print("certificate") new_secure_packet = HandshakePacket(status=0, pk=self.datasentA, signature=sign_A, nonce=nonceA, cert=certA,certChain = self.chainA) self.transport.write(new_secure_packet.__serialize__()) print("first craphanshake has ended")
def transform(self, data): oaep_padding = padding.OAEP( mgf=padding.MGF1(algorithm=self._hash_cls()), algorithm=self._hash_cls(), label=None) return self._key.decrypt(data, oaep_padding)
def main(): """ pip install cryptography OpenSSL backend Python Cryptographic Authority (PyCA) https://github.com/pyca """ # INFO or DEBUG logging.basicConfig(level=logging.INFO) # Input file filename = sys.argv[1] # RSA parameters public_exponent = 65537 key_size = 2048 param_hash = hashes.SHA256() rsa_padding = padding.PSS(mgf=padding.MGF1(param_hash), salt_length=padding.PSS.MAX_LENGTH) openssl_backend = default_backend() # Timing variables key_time = 0 sign_time = 0 verify_time = 0 logging.info( "Started PyCA RSA with public_exponent: %s, key_size: %s, rsa_padding: %s, sha: %s, backend: %s", public_exponent, key_size, str(rsa_padding.name), str(param_hash.name), str(openssl_backend.name)) with open(filename, "r") as f: # skip file reading time as well start = time.time() for m in f: logging.debug(m) start_keygen = time.time() private_key = rsa.generate_private_key(public_exponent, key_size, openssl_backend) public_key = private_key.public_key() key_time += time.time() - start_keygen start_sign = time.time() signature = private_key.sign(m, rsa_padding, param_hash) sign_time += time.time() - start_sign start_verify = time.time() try: public_key.verify(signature, m, rsa_padding, param_hash) logging.debug("Verified: True") except InvalidSignature as e: logging.warn("InvalidSignature: %s", e.message) exit(1) verify_time += time.time() - start_verify sum_time = key_time + sign_time + verify_time logging.info("Total time cost for generating key is: " + str(key_time) + " s") logging.info("Total time cost for signing the message is: " + str(sign_time) + " s") logging.info("Total time cost for verifying the message is: " + str(verify_time) + " s") logging.info( "Total time cost for key generating, message signing and verifying: " + str(sum_time) + " s") logging.info("Total time cost for system time: " + str(time.time() - start) + " s")