def main(): # Argument validations # Arguments must include flags: server_address = input("Enter server address: ") image_path = 'img\\' + input("Enter image name: ") local_key_path = 'key\\' + input("Enter your private key name: ") # Image instance image = BMP(image_path) # Diffie-Hellman process for generating a DES key des_key = diffie_hellman((server_address, 12345)) # Key, cipher, hash and signer creation key_file = open(local_key_path, 'r') local_key = RSA.importKey(key_file.read()) key_file.close() des_iv = b'12345678' des_cipher = DES.new(des_key, DES.MODE_CBC, des_iv) signer = Signature.new(local_key) plaintext = image.pixels hash = SHA.new(bytes(plaintext)) if len(plaintext) % 8 != 0: padding = 8 - (len(plaintext) % 8) plaintext += b'x' * padding else: padding = 0 ciphertext = des_cipher.encrypt(bytes(plaintext)) image.pixels = ciphertext BMP.create_image(image, "cipher.bmp") image_bytes = image.get_bytes() signature = signer.sign(hash) # Creating the connection with the server and sending connection = socket.socket() connection.connect((server_address, 12345)) connection.send('ci'.encode()) send_msg(connection, image_bytes) send_msg(connection, signature) connection.send(padding.to_bytes(1, 'little'))
def handle(self): print('Processing request from {}'.format(self.client_address[0])) type = self.connection.recv(2) req = type.decode() if req == 'dh': print('Processing Diffie-Hellman') g = random.randint(100, 9999999) n = random.randint(10000000, 99999999) gn_pair = str(g) + ' ' + str(n) self.connection.send(gn_pair.encode()) # Send byte codification of g and n remote_k = int.from_bytes(self.connection.recv(128), byteorder='little', signed=False) # Prompt for local 'e' value and generate local key from g^e mod n local_exponent = random.randint(100, 10000) local_k = pow(g, local_exponent) % n # Generating the key # Sending the local generated key in 128 unsigned byte length self.connection.send(local_k.to_bytes(128, byteorder='little', signed=False)) # Finally generate the shared private key k = str(pow(remote_k, local_exponent) % n).rjust(8, '0') print('Done, private shared key: {}\n=======================\n'.format(k)) file = os.open("src\\server\\tmp\\" + self.client_address[0], os.O_CREAT | os.O_TRUNC | os.O_RDWR) os.write(file, b'\x00'*8) memory_file = mmap.mmap(file, 8) memory_file.flush() memory_file.write(k.encode()) elif req == 'ci': print('Receiving image') key_path = 'key\\' + input("Enter the sender's public key name: ") key_file = open(key_path, 'rb') key = RSA.importKey(key_file.read()) signer = Signature.new(key) hash = SHA.new() # Receiving the rest of the messages # First the image raw_image = recv_msg(self.connection) # Then the signature signature = recv_msg(self.connection) # Finally the padding raw_padding = self.connection.recv(1) padding = int.from_bytes(raw_padding, 'little') # Writing the ciphered image to a file file = open('src\\server\\cipher.bmp', 'wb') file.write(raw_image) file.close() image = BMP('src\\server\\cipher.bmp') ciphertext = image.pixels fd = os.open("src\\server\\tmp\\" + self.client_address[0], os.O_RDONLY, mode=0o555) des_key = os.read(fd, 8) decipher = DES.new(des_key, DES.MODE_CBC, b'12345678') if padding == 0: plaintext = decipher.decrypt(bytes(ciphertext)) else: plaintext = decipher.decrypt(bytes(ciphertext))[:-padding] image.pixels = plaintext hash = SHA.new(plaintext) signer = Signature.new(key) if signer.verify(hash, signature): print('Image signature validated, writing\n====================\n') BMP.create_image(image, 'src\\server\\plain.bmp') else: print('Image signature invalid\n==============================\n') self.finish()
def handle(self): print('Processing request from {}'.format(self.client_address[0])) type = self.connection.recv(2) req = type.decode() if req == 'dh': print('Processing Diffie-Hellman') g = random.randint(100, 9999999) n = random.randint(10000000, 99999999) gn_pair = str(g) + ' ' + str(n) self.connection.send( gn_pair.encode()) # Send byte codification of g and n remote_k = int.from_bytes(self.connection.recv(128), byteorder='little', signed=False) # Prompt for local 'e' value and generate local key from g^e mod n local_exponent = random.randint(100, 10000) local_k = pow(g, local_exponent) % n # Generating the key # Sending the local generated key in 128 unsigned byte length self.connection.send( local_k.to_bytes(128, byteorder='little', signed=False)) # Finally generate the shared private key k = str(pow(remote_k, local_exponent) % n).rjust(8, '0') print('Done, private shared key: {}\n=======================\n'. format(k)) file = os.open("src\\server\\tmp\\" + self.client_address[0], os.O_CREAT | os.O_TRUNC | os.O_RDWR) os.write(file, b'\x00' * 8) memory_file = mmap.mmap(file, 8) memory_file.flush() memory_file.write(k.encode()) elif req == 'ci': print('Receiving image') key_path = 'key\\' + input("Enter the sender's public key name: ") key_file = open(key_path, 'rb') key = RSA.importKey(key_file.read()) signer = Signature.new(key) hash = SHA.new() # Receiving the rest of the messages # First the image raw_image = recv_msg(self.connection) # Then the signature signature = recv_msg(self.connection) # Finally the padding raw_padding = self.connection.recv(1) padding = int.from_bytes(raw_padding, 'little') # Writing the ciphered image to a file file = open('src\\server\\cipher.bmp', 'wb') file.write(raw_image) file.close() image = BMP('src\\server\\cipher.bmp') ciphertext = image.pixels fd = os.open("src\\server\\tmp\\" + self.client_address[0], os.O_RDONLY, mode=0o555) des_key = os.read(fd, 8) decipher = DES.new(des_key, DES.MODE_CBC, b'12345678') if padding == 0: plaintext = decipher.decrypt(bytes(ciphertext)) else: plaintext = decipher.decrypt(bytes(ciphertext))[:-padding] image.pixels = plaintext hash = SHA.new(plaintext) signer = Signature.new(key) if signer.verify(hash, signature): print( 'Image signature validated, writing\n====================\n' ) BMP.create_image(image, 'src\\server\\plain.bmp') else: print( 'Image signature invalid\n==============================\n' ) self.finish()