Socket programming - Nifalnasar/Fundamentals-of-Network GitHub Wiki
TASK 1 : Socket program for the communication between single client and single sever without in any encryption(one way)
TASK 2 : Socket program for the communication between single client and single sever with rsa encryption (one way)
SOURCE CODE for server
rsaserver.py
import socket
import rsa # Ensure you have the rsa package installed
public_key, private_key = rsa.newkeys(2048)
with open("public.pem", "wb") as f:
f.write(public_key.save_pkcs1("PEM"))
with open("private.pem", "wb") as f:
f.write(private_key.save_pkcs1("PEM"))
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 12345)
server_socket.bind(server_address)
# Listen for incoming connections
server_socket.listen(1)
print("Waiting for a connection...")
# Accept a connection
client_socket, client_address = server_socket.accept()
print(f"Connection from {client_address}")
while True:
# Receive data from the client
data = client_socket.recv(1024)
# Check if there is no more data
if not data:
break
# Load the private key from file
with open("private.pem", "rb") as f:
private_key = rsa.PrivateKey.load_pkcs1(f.read())
# Decrypt the received data using the private key
plain_text = rsa.decrypt(data, private_key)
# Print the decrypted message
print(f"Received: {plain_text.decode()}")
# Close the client and server sockets
client_socket.close()
server_socket.close()
Source Code for client:
rsaclient.py
import socket
import rsa # Make sure to have the rsa package installed
# Create a socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Server address and port
server_address = ('localhost', 12345)
# Connect to the server
client_socket.connect(server_address)
while True:
# Get user input for the message
message = input("Enter a message: ")
# Store the original message to check for the 'exit' condition
msg = message
# Load the server's public key from the 'public.pem' file
with open("public.pem", "rb") as f:
public_key = rsa.PublicKey.load_pkcs1(f.read())
# Encrypt the message using the server's public key
encrypted_message = rsa.encrypt(message.encode(), public_key)
# Send the encrypted message to the server
client_socket.send(encrypted_message)
# Check if the user entered 'exit' to exit the loop
if msg == 'exit':
break
# Close the client socket
client_socket.close()
TASK 3: Socket program to implement to way communication between the client and sever with encryption
SOurce Code for Server
2wayrsaserver.py
import socket
import rsa # Make sure to have the rsa package installed
# Generating RSA key pairs for the server and client
public_key_server, private_key_server = rsa.newkeys(2048)
with open("public_server.pem", "wb") as f:
f.write(public_key_server.save_pkcs1())
with open("private_server.pem", "wb") as f:
f.write(private_key_server.save_pkcs1())
public_key_client, private_key_client = rsa.newkeys(2048)
with open("public_client.pem", "wb") as f:
f.write(public_key_client.save_pkcs1())
with open("private_client.pem", "wb") as f:
f.write(private_key_client.save_pkcs1())
# Create a socket for the server
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Define the server's IP address and port
host = '0.0.0.0' # 0.0.0.0 binds to all available network interfaces
port = 12345
# Bind the socket to the address and port
server_socket.bind((host, port))
# Listen for incoming connections
server_socket.listen()
print(f"Server listening on {host}:{port}")
# Accept a connection from a client
client_socket, client_address = server_socket.accept()
print(f"Accepted connection from {client_address}")
while True:
# Receive data from the client
client_data = client_socket.recv(1024)
# Load the server's private key
with open("private_server.pem", "rb") as f:
private_key_server = rsa.PrivateKey.load_pkcs1(f.read())
# Decrypt the client's data using the server's private key
plain_text = rsa.decrypt(client_data, private_key_server)
if not client_data:
break
# Print the received data from the client
print(f"Client: {plain_text.decode('utf-8')}")
# Send a response to the client
server_response = input("Server: ")
# Check if the server wants to exit
srv_msg = server_response
if srv_msg == 'exit':
server_socket.close()
exit()
# Load the client's public key
with open("public_client.pem", "rb") as f:
public_key_client = rsa.PublicKey.load_pkcs1(f.read())
# Encrypt the server's response using the client's public key
msg_to_client = rsa.encrypt(server_response.encode('utf-8'), public_key_client)
client_socket.send(msg_to_client)
# Close the client and server sockets
client_socket.close()
server_socket.close()
Source Code for Client
2wayrsaclient.py
import socket
import rsa
# Create a socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Define the server's IP address and port
host = '127.0.0.1' # Change this to the server's IP address
port = 12345
# Connect to the server
client_socket.connect((host, port))
while True:
# Send a message to the server
client_message = input("Client: ")
msg = client_message
# Load the server's public key from 'public_server.pem'
with open("public_server.pem", "rb") as f:
public_key_server_data = f.read()
public_key_server = rsa.PublicKey.load_pkcs1(public_key_server_data)
# Encrypt the message using the server's public key
message = rsa.encrypt(client_message.encode('utf-8'), public_key_server)
client_socket.send(message)
if msg == 'exit':
exit()
# Receive the response from the server
with open("private_client.pem", "rb") as f:
private_key_client_data = f.read()
private_key_client = rsa.PrivateKey.load_pkcs1(private_key_client_data)
server_response = client_socket.recv(1024)
plain_text = rsa.decrypt(server_response, private_key_client)
print(f"Server: {plain_text.decode('utf-8')}")
# Close the client socket
client_socket.close()
Task 4: To implement the concept that show in the figure given below using socket programming and creating a chat room for client1 and client2 where server is the key distributer
Source Code for Server
admin.py
import socket
import threading
import rsa
# Generating the public key and the private key
public_key, private_key = rsa.newkeys(1024)
# Save the public key in a file
with open("public.pem", "wb") as f:
f.write(public_key.save_pkcs1("PEM"))
# Save the private key in a file
with open("private.pem", "wb") as f:
f.write(private_key.save_pkcs1("PEM"))
# Define the server host and port
HOST = '0.0.0.0' # Listen on all available network interfaces
PORT = 12345
# Create a socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the host and port
server_socket.bind((HOST, PORT))
# Listen for incoming connections
server_socket.listen(2) # Allow up to 2 clients to connect
# List to hold client connections
client_connections = []
def handle_client(client_socket):
while True:
try:
# Receive a message from the client
message = client_socket.recv(1024)
if not message:
break
# Load the server's private key for decryption
with open("private.pem", "rb") as f:
private_key = rsa.PrivateKey.load_pkcs1(f.read())
# Decrypt the received message
plain_text = rsa.decrypt(message, private_key)
# Decode the decrypted message from bytes to a string
plain_text = plain_text.decode('utf-8')
if plain_text == 'exit':
break
# Broadcast the message to all connected clients
for connection in client_connections:
if connection != client_socket:
# Load the recipient's public key for encryption
with open("public.pem", "rb") as f:
public_key = rsa.PublicKey.load_pkcs1(f.read())
# Encrypt the message for the recipient
plain_text = rsa.encrypt(plain_text.encode(), public_key)
# Send the encrypted message to the recipient
connection.send(plain_text)
except ConnectionResetError:
break
# Remove the disconnected client from the list
client_connections.remove(client_socket)
client_socket.close()
while True:
print("Server is listening for incoming connections...")
# Accept a connection from a client
client_socket, client_address = server_socket.accept()
print(f"Accepted connection from {client_address}")
client_connections.append(client_socket)
# Create a new thread to handle the client
client_thread = threading.Thread(target=handle_client, args=(client_socket,))
client_thread.start()
Same Code for both Clients:
cilent.py
import socket
import threading
import rsa
# Define the server host and port
HOST = '10.0.2.15' #server's IP address
PORT = 12345
# Function to receive and display messages from the server
def receive_messages(client_socket):
while True:
try:
# Receive a message from the server
message = client_socket.recv(1024)
with open("private.pem", "rb") as f:
private_key = rsa.PrivateKey.load_pkcs1(f.read())
# Decrypt the received message using the client's private key
plain_text = rsa.decrypt(message, private_key)
if plain_text == 'exit':
break
print("\n")
print(f"Received: {plain_text.decode()}")
except ConnectionResetError:
print("Disconnected from the server.")
break
# Create a socket for the client
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to the server using the defined host and port
client_socket.connect((HOST, PORT))
# Start a thread to receive and display messages from the server
receive_thread = threading.Thread(target=receive_messages, args=(client_socket,))
receive_thread.start()
# Send messages to the server
while True:
with open("public.pem", "rb") as f:
public_key = rsa.PublicKey.load_pkcs1(f.read())
# Read a message from the user
message = input("Enter the message to send: ")
if message == 'exit':
break
else:
# Encrypt the message using the server's public key and send it
message = rsa.encrypt(message.encode(), public_key)
client_socket.send(message)