def cipher_content(self, previous_hash, username, amount, signature, certificate): rsa_kg = RSAKGen() auction_sym = Fernet.generate_key() fernet = Fernet(auction_sym) if self.type == BLIND_AUCTION: amount = fernet.encrypt(amount) #amount = rsa_kg.cipher_public_key(self.auction_user_key, amount) # Hybrid cipher # cipher with sym key username = fernet.encrypt(username) signature = fernet.encrypt(signature) certificate = fernet.encrypt(certificate) # cipher key with auction pub key key = rsa_kg.cipher_public_key(self.auction_public_key, auction_sym) # assinada a simetric key com a pub key do auction second_key = Fernet.generate_key() fernet = Fernet(second_key) key = fernet.encrypt(key) # # cipher key again with auction owner pub key second_key = rsa_kg.cipher_public_key(self.auction_user_key, second_key) block = Block(previous_hash, amount, signature, username, certificate, key, second_key) return block
def __init__(self, sock): # Create the Entity and socket self.auction_repository = AuctionRepositoryEntity() self.sock = sock # Create the Public key and Private key rsa_kg = RSAKGen() # Check for the existence of the directory if check_directory(self._server_path): try: # Get the keys from the folders self.auction_repository.private_key, self.auction_repository.public_key = rsa_kg.load_key_servers( self._server_path, self._server_password) # Get the server public key self.auction_repository.manager_public = rsa_kg.load_public_key( self._server_path, "manager_server.pem") except ValueError: # Exits sys.exit( "The password is incorrect! All information has been deleted and the server will" "now become unstable") else: # Since it doesn't exist, we create the folders os.mkdir(self._server_path) os.mkdir(os.getcwd() + "/Clients") self.auction_repository.private_key, self.auction_repository.public_key = rsa_kg.generate_key_pair_server( ) rsa_kg.save_keys_server(self._server_path, self._server_password)
def __init__(self, auction_time, auction_type, auction_user_key, auction_user, auction_name=None, description=None, auction_max_number_bids=10, auction_min_number_bids=10, auction_allowed_bidders=None, auction_threshold=None): self.auction_user_key = auction_user_key self.auction_user = auction_user self.description = description self.auction_name = auction_name self.id = uuid.uuid1() self.auction_time = auction_time self.type = auction_type self.auction_max_number_bids = int(auction_max_number_bids) self.auction_min_number_bids = int(auction_min_number_bids) self.blockchain = [] self.begin_date = datetime.datetime.now() self.max_date = datetime.datetime(year=self.begin_date.year, month=self.begin_date.month, day=self.begin_date.day, hour=self.begin_date.hour + int(auction_time)) self.open = True # Assymetric key pair to cipher the bid's information rsa_kg = RSAKGen() self.auction_private_key, self.auction_public_key = rsa_kg.generate_key_pair_server( )
def build_trust(self, message_json): sk = self.auction_repository.session_key_clients[ message_json["username"]] # VERIFYES THE message integrity if not HMAC_Conf.verify_function("certificate", message_json, sk): return base64.b64encode( "{ \"type\" : \"Tempered data\"}".encode('utf-8')) # decipher with the session key cert = unpadd_data( message_json["certificate"], self.auction_repository.session_key_clients[ message_json["username"]]) signature = unpadd_data( message_json["digital_signature"], self.auction_repository.session_key_clients[ message_json["username"]]) certificate = x509.load_pem_x509_certificate(cert, default_backend()) citizen = CitizenCard() print(signature) if not citizen.check_signature( certificate, signature, message_json["username"].encode('utf-8')): return base64.b64encode( "{ \"type\" : \"No valid signature\"}".encode('utf-8')) if not citizen.validate_certificate(certificate): return base64.b64encode( "{ \"type\" : \"No valid certificate\"}".encode('utf-8')) user_pub_key = unpadd_data( message_json["public"], self.auction_repository.session_key_clients[ message_json["username"]]) # Get the user key from the dir user_key = serialization.load_pem_public_key(user_pub_key, backend=default_backend()) rsa = RSAKGen() # Verify the user signature of the session key if rsa.verify_sign( message_json["rsa_signature"].encode('utf-8'), self.auction_repository.session_key_clients[ message_json["username"]], user_key): # It is invalid return base64.b64encode( "{\"type\" : \"No valid rsa signature\"}".encode("utf-8")) _dir = os.getcwd() + "/Clients/" + message_json["username"] if not check_directory(_dir): if not check_directory(os.getcwd() + "/Clients"): os.mkdir(os.getcwd() + "/Clients") os.mkdir(_dir) with open(_dir + "/" + PK_NAME, "wb") as file: file.write(user_pub_key) return base64.b64encode("{\"type\" : \"success\"}".encode("utf-8"))
def auction_to_view(self, message_json): username = message_json["username"] sk = self.auction_repository.session_key_clients[username] hm = base64.b64decode(message_json["hmac"]) cr = message_json["message"].encode() if not HMAC_Conf.verify_integrity(hm, cr, sk): return base64.b64encode( "{ \"type\" : \"Tempered data\"}".encode('utf-8')) # Decrypts the message data = decrypt_data(sk, message_json["message"], base64.b64decode(message_json["iv"]), base64.b64decode(message_json["Key"]), self.auction_repository.private_key) auction_id = unpadd_data(data, sk) auction = self.auction_repository.auctions[str(auction_id, "utf-8")] blockchain = pickle.dumps(auction.blockchain) # cipher first the blockchain enc_bl = encrypt_message_sk( blockchain, self.auction_repository.session_key_clients[username]) message = "{ \"type\" : \"auction_to_view\", \n" message_int = "{\n\"auction_id\" : \"" + encrypt_message_sk( auction_id, sk) + "\" ,\n" message_int += "\"blockchain\" : \"" + enc_bl + "\", \n" message_int += "\"auct_type\" : \"" + encrypt_message_sk( auction.type, sk) + "\",\n" message_int += "\"avail\" : \"" + encrypt_message_sk( str(auction.open), sk) + "\"\n" message_int += "}" rsa_kg = RSAKGen() client_pub = rsa_kg.load_public_key(os.getcwd() + "/Clients/" + username) enc_json_message = encrypt_message_complete( base64.b64encode(message_int.encode("utf-8")), sk, client_pub) key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] hmac = HMAC_Conf.integrity_control( data.encode(), self.auction_repository.session_key_clients[username]) message += "\"message\" : \"" + data + "\",\n" message += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8') + "\", \n" message += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\"\n" message += "}" return base64.b64encode(message.encode("utf-8"))
def create_session_key_server(self, message_json, address): # decode the params parameters = pickle.loads( codecs.decode(message_json["params"].encode(), "base64")) par = load_pem_parameters(parameters, backend=default_backend()) # Get the server public key manager_pub = message_json["public"].encode() save_server_key_client(self._server_path, manager_pub, "/manager_server.pem") # Load the key r = RSAKGen() self.auction_repository.manager_public = r.load_public_key( self._server_path, "manager_server.pem") # Generate our public/private key private_key = par.generate_private_key() public_key = private_key.public_key() # Get the public key from the user peer_public_key_bytes = message_json["pk"].encode() peer_public_key = serialization.load_pem_public_key( peer_public_key_bytes, default_backend()) shared_key = private_key.exchange(peer_public_key) calendar_date = str(datetime.datetime.now()) derived_key = HKDF(algorithm=hashes.SHA256(), length=DH_HKDF_KEY, salt=None, info=calendar_date.encode(), backend=default_backend()).derive(shared_key) # Construct the message with the keys message = "{ \"type\" : \"session_server\" ,\n" # Now send our DH public key to the client pk_dh = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( 'utf-8') message += "\"pk\" : \"" + pk_dh + "\" ,\n" message += "\"info\" : \"" + calendar_date + "\",\n" message += "\"server_key\" : \"" + self.auction_repository.public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( 'utf-8') + "\"" message += "}" # Set the sessionKey as the bytes of the derived_key self.auction_repository.session_key_server = derived_key return base64.b64encode(message.encode('utf-8'))
def create_session_key_server(self): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Our parameters parameters = dh.generate_parameters(generator=5, key_size=utils_app.DH_KEY_SIZE, backend=default_backend()) # Our private key and public key private_key = parameters.generate_private_key() public_key = private_key.public_key() message = codecs.encode( pickle.dumps(parameters.parameter_bytes(encoding=Encoding.PEM, format=ParameterFormat.PKCS3)), "base64").decode() # message construction json_message = "{ " + "\n" json_message += "\"type\" : \"session_server\"," + "\n" json_message += "\"params\" : \"" + message + "\", \n" json_message += "\"pk\" : \"" + public_key.public_bytes(encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo)\ .decode('utf-8') + "\"," json_message += "\"public\" : \"" + self.auction_manager.public_key.\ public_bytes(encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo)\ .decode('utf-8') + "\"" json_message += "}" try: # send type sock.sendto(base64.b64encode(json_message.encode('utf-8')), utils_app.AR_ADDRESS) # Receive type data, server = sock.recvfrom(utils_app.SOCKET_BYTES) json_message = json.loads(base64.b64decode(data), strict=False) # derivate the key peer_public_key_bytes = json_message["pk"].encode() peer_public_key = serialization.load_pem_public_key(peer_public_key_bytes, default_backend()) shared_key = private_key.exchange(peer_public_key) derived_key = cryptography.hazmat.primitives.kdf.hkdf.HKDF(algorithm=hashes.SHA256(), length=utils_app.DH_HKDF_KEY, salt=None, info=json_message["info"].encode(), backend=default_backend()).derive(shared_key) self.auction_manager.session_key_repository = derived_key save_server_key_client(self._server_path, json_message["server_key"].encode(), "/repository_server.pem") #Load the key r = RSAKGen() self.auction_manager.public_repository_key = r.load_public_key(os.getcwd()+"/server", "repository_server.pem") print("Session Set with repository") finally: sock.close()
def close(self): self.open = False rsa_kg = RSAKGen() for bid in self.blockchain: # decipher first sym key with second sym key fernet = Fernet(bid.second_symmetric_key) sym_key = fernet.decrypt(bid.first_symmetric_key) # decipher first sym key with auction pub key sym_key = rsa_kg.decipher_with_private_key( self.auction_private_key, sym_key) bid.first_symmetric_key = sym_key
def list_auctions(self, message_json): sk = self.auction_repository.session_key_clients[ message_json["username"]] # VERIFYES THE message integrity if not HMAC_Conf.verify_function("username", message_json, sk): return base64.b64encode( "{ \"type\" : \"Tempered data\"}".encode('utf-8')) # gets the list of auctions and serializes it auction_list = self.auction_repository.listAuctions() serialized = pickle.dumps(auction_list) # loads the shared secret between the server and the user username = message_json["username"] session_key = self.auction_repository.session_key_clients[username] list_auc = encrypt_message_sk(serialized, session_key) rsa_kg = RSAKGen() client_pub = rsa_kg.load_public_key(os.getcwd() + "/Clients/" + username) enc_json_message = encrypt_message_complete( base64.b64encode(list_auc.encode("utf-8")), sk, client_pub) message = "{ \"type\" : \"list_auctions\" ,\n" key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] hmac = HMAC_Conf.integrity_control( data.encode(), self.auction_repository.session_key_clients[username]) message += "\"list\" : \"" + data + "\", \n" message += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8') + "\", \n" message += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\"\n" message += "}" print("auction_repos", message) return base64.b64encode(message.encode("utf-8"))
def __init__(self, sock): self.sock = sock self.auction_manager = AuctionManagerEntity() # Create the Public key and Private key rsa_kg = RSAKGen() # Check for the existence of the directory if check_directory(self._server_path): try: self.auction_manager.private_key, self.auction_manager.public_key = rsa_kg.load_key_servers( self._server_path,self._server_password) self.auction_manager.public_repository_key = rsa_kg.load_public_key(os.getcwd()+"/server", "repository_server.pem") except ValueError: print("The password is incorrect!" "All information has been deleted and the server will now become instable") sys.exit(0) else: os.mkdir(self._server_path) self.auction_manager.private_key, self.auction_manager.public_key = rsa_kg.generate_key_pair_server() rsa_kg.save_keys_server(self._server_path, self._server_password) # Create the sessionKey with the other Repository self.create_session_key_server()
def trust_server(self,client, challenge): # loads citizen card rsa = RSAKGen() citizen = CitizenCard() certificate = citizen.load_authentication_certificate() self.digital_signature = citizen.digital_signature(challenge) self.last = client.username digital_signature = self.digital_signature rsa_sign = rsa.sign_message(client.username.encode('utf-8'), client.private_key) # builds trust message json_message = "{\n\"rsa_signature\" : \"" + str(base64.b64encode(rsa_sign), "utf-8")+ "\", \n" json_message += "\"username\" : \"" + client.username + "\", \n" json_message += "\"certificate\" : \"" + str(base64.b64encode(certificate.public_bytes(serialization.Encoding.PEM)), "utf-8") + "\", \n" json_message += "\"digital_signature\" : \"" + str(base64.b64encode(digital_signature), "utf-8") + "\" \n}" return json_message
def close_auction(self, client, message_json): # VERIFYES THE message integrity if not HMAC_Conf.verify_function("message", message_json, client.session_key_repository): return base64.b64encode("{ \"type\" : \"Tempered data\"}".encode('utf-8')) # Decrypts the message data = decrypt_data(client.session_key_repository, message_json["message"], base64.b64decode(message_json["iv"]), base64.b64decode(message_json["Key"]), client.private_key) data_json = json.loads(data, strict="false") something = unpadd_data(data_json["blockchain"], client.session_key_repository) blockchain = pickle.loads(something) rsa_kg = RSAKGen() for bid in blockchain: bid.second_symmetric_key = rsa_kg.decipher_with_private_key(client.auction_private_key, bid.second_symmetric_key) bloc_chain_enc = encrypt_message_sk(pickle.dumps(blockchain), client.session_key_repository) message = "{ \"type\" : \"close_auction\" ,\n" message += "\"username\" : \"" + client.username + "\" ,\n" message_interm = "{" message_interm += "\"auction_id\" : \"" + data_json["auction_id"]+ "\",\n" message_interm += "\"blockchain\" : \"" + bloc_chain_enc + "\"\n" message_interm += "}" enc_json_message = encrypt_message_complete(base64.b64encode(message_interm.encode("utf-8")), client.session_key_repository, client.server_public_key_repository) key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] hmac = HMAC_Conf.integrity_control(data.encode(),client.session_key_repository) message += "\"message\" : \"" + data + "\" ,\n" message += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\",\n" message += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8') + "\"\n" message += "}" return message, AR_ADDRESS
def save_receipt(self, client, message_json): # VERIFIES THE message integrity if not HMAC_Conf.verify_function("message", message_json, client.session_key_repository): return base64.b64encode("{ \"type\" : \"Tempered data\"}".encode('utf-8')) # Decrypts the message data = decrypt_data(client.session_key_repository, message_json["message"], base64.b64decode(message_json["iv"]), base64.b64decode(message_json["Key"]), client.private_key) message_json = json.loads(data, strict="false") timestamp = unpadd_data(message_json["timestamp"], client.session_key_repository) server_signature = unpadd_data(message_json["server_signature"], client.session_key_repository) auction_id = unpadd_data(message_json["auction_id"], client.session_key_repository) bid_amount = unpadd_data(message_json["bid_amount"], client.session_key_repository) bid_signature = unpadd_data(message_json["bid_signature"], client.session_key_repository) bloc_hash = unpadd_data(message_json["bloc_hash"], client.session_key_repository) receipt_unique_hash = unpadd_data(message_json["receipt_unique_hash"], client.session_key_repository) bidder = unpadd_data(message_json["bidder"], client.session_key_repository) rsa_kg = RSAKGen() citizen = CitizenCard() result = rsa_kg.verify_sign(server_signature, bloc_hash, client.server_public_key_repository) if not result: print("The receipt signature is not valid") return cert = citizen.load_authentication_certificate() result = citizen.check_signature(cert, bid_signature, bid_amount) if not result: print("The client signature is not valid") return if citizen.load_name() != str(bidder,"utf-8"): print("The bidder name is not the same as the citizen card") return receipt = create_receipt(timestamp,auction_id,server_signature,bid_amount,bid_signature,receipt_unique_hash,bloc_hash, str(bidder,"utf-8")) file = open(os.getcwd() + "/" + client.username + "/receipts/"+str(auction_id,"utf-8")+"_"+str(timestamp,"utf-8")+".json","w") json.dump(receipt, file)
def login(self): rsa_gen = RSAKGen() print("\n") username = input("Username: "******"password: "******"/" + username # Check existence if check_directory(self._client_path): try: keys = rsa_gen.load_key_clients(self._client_path, password) except ValueError: print("\nPassword Entered was incorrect!") sys.exit(0) # Private key current_client.private_key = keys[0] current_client.public_key = keys[1] current_client.auction_private_key = keys[2] current_client.auction_public_key = keys[3] current_client.server_public_key_manager = rsa_gen.\ load_public_key(self._client_path,"server_manager.pem") current_client.server_public_key_repository = rsa_gen.\ load_public_key(self._client_path,"server_repository.pem") else: os.mkdir(self._client_path) os.mkdir(self._client_path+"/receipts") keys = rsa_gen.generate_key_pair_client() # Private key current_client.private_key = keys[0] current_client.public_key = keys[1] current_client.auction_private_key = keys[2] current_client.auction_public_key = keys[3] rsa_gen.save_keys_client(self._client_path, password) current_client.server_public_key_manager = self.ask_for_pubkey(AM_ADDRESS) current_client.server_public_key_repository = self.ask_for_pubkey(AR_ADDRESS) save_server_key_client(os.getcwd()+"/" + current_client.username, current_client.server_public_key_manager.public_bytes( encoding= serialization.Encoding.PEM, format= serialization.PublicFormat.SubjectPublicKeyInfo), AM_S_C_KEY) save_server_key_client(os.getcwd()+"/" + current_client.username, current_client.server_public_key_repository.public_bytes( encoding= serialization.Encoding.PEM, format= serialization.PublicFormat.SubjectPublicKeyInfo), AR_S_C_KEY) # builds DH # current_client.initialize_session_key(AM_ADDRESS, self) current_client.initialize_session_key(AR_ADDRESS, self) return current_client
def create_auction(self, client): message = "{ \"type\" : \"create_auction\" ,\n" message += "\"username\" : \"" + client.username + "\",\n" # Now ask for all the details print("\n") # Verify the fields # Auction needs a name auction_name = input("Auction name: ") while auction_name == "": auction_name = input("Auction name: ") # If there is no description then put it as None auction_description = input("Auction description: ") if auction_description == "": auction_description = "None" # If no given minimum the put it at zero $ auction_min_number_bids = input("Minimum price bid: ") if auction_min_number_bids == "": auction_min_number_bids = "0" # There needs to be a limit auction_time = input("Auction time limit (Hrs): ") while int(auction_time) < 0: auction_time = input("Auction time limit (Hrs): ") # If there is no max bids then 0 auction_max_number_bids = input("Auction maximum number of bids: ") if auction_max_number_bids == "": auction_max_number_bids = "0" # If there is no given names then put it as None auction_allowed_bidders = input("Auction allowed bidders (separate with [,]): ") if auction_allowed_bidders == "": auction_allowed_bidders = "None" # There must have a type auction_type = input("Auction type ((B)lind or (N)ormal): ") if auction_type.lower() in ["b", "blind"]: auction_type = BLIND_AUCTION print("Blind auction is being created...") else: auction_type = ENGLISH_AUCTION print("Normal auction is being created...") # sign the session key rsa = RSAKGen() signature = rsa.sign_message(client.session_key_manager,client.auction_private_key) auction_json_message = "{\"auction_name\" : \"" + encrypt_message_sk(auction_name, client.session_key_manager)+ "\" ,\n" auction_json_message += "\"auction_description\" : \"" + encrypt_message_sk(auction_description, client.session_key_manager) + "\" ,\n" auction_json_message += "\"auction_min_number_bids\" : \"" + encrypt_message_sk(auction_min_number_bids, client.session_key_manager) + "\",\n" auction_json_message += "\"auction_time\" : \"" + encrypt_message_sk(auction_time, client.session_key_manager) + "\" ,\n" auction_json_message += "\"auction_max_number_bids\" : \"" + encrypt_message_sk(auction_max_number_bids, client.session_key_manager) + "\" ,\n" auction_json_message += "\"auction_allowed_bidders\" : \"" + encrypt_message_sk(auction_allowed_bidders, client.session_key_manager) + "\" ,\n" auction_json_message += "\"auction_type\" : \""+ encrypt_message_sk(auction_type, client.session_key_manager) + "\" ,\n" # now put our public auction key and a signature to prove that he has the private key auction_json_message += "\"auction_user_key\" : \"" + encrypt_message_sk(get_public_key_bytes(client.auction_public_key), client.session_key_manager) + "\", \n" auction_json_message += "\"auction_signature\" : \"" + encrypt_message_sk(str(base64.b64encode(signature), 'utf-8'), client.session_key_manager)+ "\" \n" auction_json_message += "}" enc_json_message = encrypt_message_complete(base64.b64encode(auction_json_message.encode("utf-8")), client.session_key_manager, client.server_public_key_manager) key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] hmac = HMAC_Conf.integrity_control(data.encode(), client.session_key_manager) message += "\"message\" : \"" + data + "\",\n" message += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8')+ "\", \n" message += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\"\n" message += "}" return message, AM_ADDRESS
def make_bid(self, message_json): sk = self.auction_repository.session_key_clients[ message_json["username"]] # VERIFIES THE message integrity if not HMAC_Conf.verify_function("message", message_json, sk): return base64.b64encode( "{ \"type\" : \"Tempered data\"}".encode('utf-8')) # Decrypts the message username = message_json["username"] data = decrypt_data( self.auction_repository.session_key_clients[username], message_json["message"], base64.b64decode(message_json["iv"]), base64.b64decode(message_json["Key"]), self.auction_repository.private_key) # Loads the message to json message_json = json.loads(data, strict="False") auction_id = unpadd_data( message_json["auction_id"], self.auction_repository.session_key_clients[username]) bidder = unpadd_data( message_json["bidder"], self.auction_repository.session_key_clients[username]) amount = unpadd_data( message_json["amount"], self.auction_repository.session_key_clients[username]) signature = unpadd_data( message_json["signature"], self.auction_repository.session_key_clients[username]) certificate = unpadd_data( message_json["certificate"], self.auction_repository.session_key_clients[username]) # validate certificate and signature cert = x509.load_pem_x509_certificate(certificate, default_backend()) citizen = CitizenCard() if not citizen.check_signature(cert, signature, amount): return base64.b64encode( "{ \"type\" : \"No valid signature\"}".encode('utf-8')) if not citizen.validate_certificate(cert): return base64.b64encode( "{ \"type\" : \"No valid certificate\"}".encode('utf-8')) auction = self.auction_repository.auctions[str(auction_id, "utf-8")] response = auction.makeBid(bidder, amount, signature, certificate) if not response: return base64.b64encode( "{ \"type\" : \"No success\"}".encode('utf-8')) # create receipt rsa_kg = RSAKGen() block = auction.blockchain[-1] server_signature = rsa_kg.sign_message( block.hash, self.auction_repository.private_key) server_signature = encrypt_message_sk(server_signature, sk) uuids = encrypt_message_sk(str(uuid.uuid1()), sk) last = encrypt_message_sk(block.hash, sk) bidder = encrypt_message_sk(bidder, sk) receipt = create_receipt(encrypt_message_sk(str(block.timestamp), sk), encrypt_message_sk(str(auction_id), sk), server_signature, encrypt_message_sk(amount, sk), encrypt_message_sk(signature, sk), uuids, last, bidder) # cipher receipt with pub_key client_pub = rsa_kg.load_public_key(os.getcwd() + "/Clients/" + username) enc_json_message = encrypt_message_complete( base64.b64encode(receipt.encode("utf-8")), sk, client_pub) key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] hmac = HMAC_Conf.integrity_control( data.encode(), self.auction_repository.session_key_clients[username]) message = "{ \"type\" : \"receipt\", \n" message += "\"message\" : \"" + data + "\",\n" message += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8') + "\", \n" message += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\"\n" message += "}" return base64.b64encode(message.encode("utf-8"))
def create_session_key_user_server(self, message_json): rsa_kg = RSAKGen() username = message_json["username"] random_key = rsa_kg.decipher_with_private_key( self.auction_repository.private_key, base64.b64decode(message_json["random_key"])) # VERIFIES THE message integrity if not HMAC_Conf.verify_function("message", message_json, random_key): return base64.b64encode( "{ \"type\" : \"Tempered data\"}".encode('utf-8')) # Decrypts the message data = decrypt_data("", message_json["message"], base64.b64decode(message_json["iv"]), base64.b64decode(message_json["Key"]), self.auction_repository.private_key) # Loads the messsage to json internal_json = json.loads(data, strict="False") rsa_signature = internal_json["rsa_signature"] certificate = base64.b64decode( internal_json["certificate"] ) #PENSO QUE TENS DE FAZER BASE64 DECODE digital_signature = base64.b64decode( internal_json["digital_signature"]) citizen = CitizenCard() certificate = x509.load_pem_x509_certificate(certificate, default_backend()) if not citizen.check_signature( certificate, digital_signature, self.auction_repository.clients_challenge[base64.b64decode( message_json["username"])].encode()): return base64.b64encode( "{ \"type\" : \"No valid signature\"}".encode('utf-8')) if not citizen.validate_certificate(certificate): return base64.b64encode( "{ \"type\" : \"No valid certificate\"}".encode('utf-8')) self.auction_repository.clients_challenge.pop( base64.b64decode(message_json["username"])) # Get the parameters parameters = pickle.loads( codecs.decode(message_json["params"].encode(), "base64")) par = load_pem_parameters(parameters, backend=default_backend()) # Generate our DH public/private key private_key = par.generate_private_key() public_key = private_key.public_key() # Get the public key bytes from the user peer_public_key_bytes = message_json["pk"].encode() peer_public_key = serialization.load_pem_public_key( peer_public_key_bytes, default_backend()) calendar_date = str(datetime.datetime.now()) shared_key = private_key.exchange(peer_public_key) derived_key = HKDF(algorithm=hashes.SHA256(), length=DH_HKDF_KEY, salt=None, info=calendar_date.encode("utf-8"), backend=default_backend()).derive(shared_key) # Construct the message with the keys message = "{ \"type\" : \"session\" ,\n" # Now send our DH public key to the client pk_dh = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( 'utf-8') message += "\"pk\" : \"" + pk_dh + "\" ,\n" message += "\"info\" : \"" + calendar_date + "\",\n" message += "\"server_key\" : \"" + self.auction_repository.public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( 'utf-8') + "\"" message += "}" # Get the username and set the session key self.auction_repository.session_key_clients[ message_json["username"]] = derived_key # Get the public key from the user key from the user _dir = os.getcwd() + "/Clients/" + message_json["username"] if not check_directory(_dir): if not check_directory(os.getcwd() + "/Clients"): os.mkdir(os.getcwd() + "/Clients") os.mkdir(_dir) with open(_dir + "/" + PK_NAME, "wb") as file: file.write(message_json["public"].encode("utf-8")) return base64.b64encode(message.encode('utf-8'))
def create_auction(self, message_json, address): username = message_json["username"] session_key_client = self.auction_manager.session_clients[username] # VERIFYES THE message integrity if not HMAC_Conf.verify_function("message", message_json, session_key_client ): return base64.b64encode("{ \"type\" : \"Tempered data\"}".encode('utf-8')) # Decrypts the message data = decrypt_data(session_key_client, message_json["message"], base64.b64decode(message_json["iv"]), base64.b64decode(message_json["Key"]), self.auction_manager.private_key) # Loads the messsage to json message_json = json.loads(data,strict="False") # Decrypt the rest of the data with the SessionKey auction_name = unpadd_data(message_json["auction_name"],session_key_client) auction_description = unpadd_data(message_json["auction_description"], session_key_client) auction_min_number_bids = unpadd_data(message_json["auction_min_number_bids"],session_key_client) auction_time = unpadd_data(message_json["auction_time"],session_key_client) auction_max_number_bids = unpadd_data(message_json["auction_max_number_bids"], session_key_client) auction_allowed_bidders = unpadd_data(message_json["auction_allowed_bidders"], session_key_client) auction_type = unpadd_data(message_json["auction_type"], session_key_client) auct_padd = unpadd_data( message_json["auction_user_key"].encode('utf-8'),session_key_client) auction_user_key = serialization.load_pem_public_key(auct_padd, default_backend()) auction_signature = unpadd_data(message_json["auction_signature"], session_key_client) rsa = RSAKGen() verification = rsa.verify_sign(base64.b64decode(auction_signature), session_key_client, auction_user_key) # if its not valid then the address is the client's and the message is an error if not verification: return base64.b64encode("{\"type\" : \"Not a valid auction signature\"}".encode("utf-8")), address # Construct the message to send to the AR message_final_json = "{" message_final_json += "\"type\" : \"create_auction\", \n" # create the encrypted message repository_key = self.auction_manager.session_key_repository # Create the interm message message_interm = "{" message_interm += "\"username\" : \"" + encrypt_message_sk(username, repository_key) + "\", \n" message_interm += "\"auction_name\" : \"" + encrypt_message_sk(auction_name, repository_key) + "\", \n" message_interm += "\"auction_description\" : \"" + encrypt_message_sk(auction_description, repository_key) + "\", \n" message_interm += "\"auction_min_number_bids\" : \"" + encrypt_message_sk(auction_min_number_bids, repository_key) + "\", \n" message_interm += "\"auction_time\" : \"" + encrypt_message_sk(auction_time, repository_key) + "\", \n" message_interm += "\"auction_max_number_bids\" : \"" + encrypt_message_sk(auction_max_number_bids, repository_key) + "\", \n" message_interm += "\"auction_allowed_bidders\" : \"" + encrypt_message_sk(auction_allowed_bidders, repository_key) + "\", \n" message_interm += "\"auction_type\" : \"" + encrypt_message_sk(auction_type, repository_key) + "\", \n" message_interm += "\"auction_user_key\" : \"" + encrypt_message_sk(auct_padd, repository_key) + "\" \n" message_interm += "}" # Encrypt Complete enc_json_message = encrypt_message_complete(base64.b64encode(message_interm.encode("utf-8")), repository_key, self.auction_manager.public_repository_key) key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] hmac = HMAC_Conf.integrity_control(data.encode(), repository_key) message_final_json += "\"message\" : \"" + data + "\",\n" message_final_json += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message_final_json += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\",\n" message_final_json += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8') + "\"\n" message_final_json += "\n}" print(message_final_json) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(base64.b64encode(message_final_json.encode("utf-8")), AR_ADDRESS) return base64.b64encode("{\"type\" : \"success\"}".encode("utf-8"))
def initialize_session_key(self, address, actions): # asks for a challenge sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) message = "{\"type\" : \"ask_challenge\"," + "\n" message += "\"username\" : \"" + self.username + "\"" + "\n" message += "}" sock.sendto(base64.b64encode(message.encode("utf-8")), address) # receives the challenge data, server = sock.recvfrom(utils_app.SOCKET_BYTES) decoded_message = base64.b64decode(data) sock.close() message = json.loads(decoded_message, strict=False) challenge = message["challenge"] # Our parameters parameters = dh.generate_parameters(generator=5, key_size=utils_app.DH_KEY_SIZE, backend=default_backend()) # Our private key and public key from DH private_key = parameters.generate_private_key() public_key = private_key.public_key() pickled_params = codecs.encode( pickle.dumps( parameters.parameter_bytes(encoding=Encoding.PEM, format=ParameterFormat.PKCS3)), "base64").decode() message = "{\"type\" : \"session_key\"," + "\n" message += "\"params\" : \"" + pickled_params + "\"," + "\n" message += "\"username\" : \"" + self.username + "\"," + "\n" message += "\"pk\" : \"" + public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( 'utf-8') + "\",\n" message += "\"public\" : \"" + self.public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo).decode( 'utf-8') + "\"," inner_message = actions.trust_server(self, challenge=challenge) enc_json_message = None server_pub = None if address == utils_app.AM_ADDRESS: server_pub = self.server_public_key_manager else: server_pub = self.server_public_key_repository enc_json_message = utilities.encrypt_message_complete( base64.b64encode(inner_message.encode("utf-8")), "", server_pub) key = enc_json_message[0] iv = enc_json_message[2] data = enc_json_message[1] rsa_kg = RSAKGen() random_key = Fernet.generate_key() hmac = HMAC_Conf.integrity_control(data.encode(), random_key) random_key = rsa_kg.cipher_public_key(server_pub, random_key) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) message += "\"message\" : \"" + data + "\",\n" message += "\"Key\" : \"" + str(base64.b64encode(key), 'utf-8') + "\",\n" message += "\"hmac\" : \"" + str(base64.b64encode(hmac), 'utf-8') + "\", \n" message += "\"random_key\" : \"" + str(base64.b64encode(random_key), 'utf-8') + "\", \n" message += "\"iv\" : \"" + str(base64.b64encode(iv), 'utf-8') + "\"\n" message += "}" sock.sendto(base64.b64encode(message.encode("utf-8")), address) #print(message) ##### Sent the parameters with all the information ##### ########################################################################################################### # Receive response data, server = sock.recvfrom(utils_app.SOCKET_BYTES) decoded_data = base64.b64decode(data).decode() json_message = json.loads(decoded_data, strict=False) if json_message["type"] == "No valid signature": print("No valid signature") sys.exit(0) elif json_message["type"] == "No valid certificate": print("No valid signature") sys.exit(0) # 'type', 'pk' -> public dh_key , 'info' -> handshake data, 'server_key' peer_pk = serialization.load_pem_public_key( json_message["pk"].encode('utf-8'), default_backend()) shared_secret = private_key.exchange(peer_pk) derived_key = hkdf.HKDF(algorithm=hashes.SHA256(), length=utils_app.DH_HKDF_KEY, salt=None, info=json_message["info"].encode('utf-8'), backend=default_backend())\ .derive(shared_secret) if address == utils_app.AM_ADDRESS: self.session_key_manager = derived_key else: self.session_key_repository = derived_key ### Recieved the key from the server and created the public key #### ############################################################################################################ sock.close()