Network Security and Cryptography: University Institute of Engineering and Technology Panjab University Chandigarh
Network Security and Cryptography: University Institute of Engineering and Technology Panjab University Chandigarh
Network Security and Cryptography: University Institute of Engineering and Technology Panjab University Chandigarh
Technology
Panjab University Chandigarh
Collecting Packets:
IP V6:
Pv4 produces 4 billion addresses, and the developers think that these addresses
are enough, but they were wrong. IPv6 is the next generation of IP addresses.
The main difference between IPv4 and IPv6 is the address size of IP addresses.
The IPv4 is a 32-bit address, whereas IPv6 is a 128-bit hexadecimal address.
ICMP V6:
ICMPv6 is used by IPv6 nodes to report errors encountered in processing packets,
and to perform other internet-layer functions, such as diagnostics (ICMPv6
"ping"). ICMPv6 is an integral part of IPv6, and the base protocol must be fully
implemented by every IPv6 node.
Internet Control Message Protocol (both ICMPv4 and ICMPv6) is a protocol
which acts as a communication messenger protocol between the
communicating devices in IP network. ICMP messages provide feedback, error
reporting and network diagnostic functions in IP networks which are necessary
for the smooth operation of IPv6.
IPV4:
Pv4 is a version 4 of IP. It is a current version and the most commonly used IP
address. It is a 32-bit address written in four numbers separated by 'dot', i.e.,
periods. This address is unique for each device.
TCP:
TCP (Transmission Control Protocol) is one of the main protocols of the
Internet protocol suite. It lies between the Application and Network Layers
which are used in providing reliable delivery services. It is a connection-
oriented protocol for communications that helps in the exchange of messages
between different devices over a network. The Internet Protocol (IP), which
establishes the technique for sending data packets between computers, works
with TCP.
ARP:
The acronym ARP stands for Address Resolution Protocol which is one of
the most important protocols of the Data link layer in the OSI model. It is
responsible to find the hardware address of a host from a known IP address.
There are three basic ARP terms. ARP finds the hardware address, also
known as the Media Access Control (MAC) address, of a host from its known
IP address.
There are 3 types of ARP:
Reverse ARP
Proxy ARP
Inverse ARP
QUIC:
QUIC (Quick UDP Internet Connections, pronounced quick) is an experimental
transport layer network protocol designed by Google. The overall goal is to
reduce latency compared to that of TCP. Think of QUIC as being similar to
TCP+TLS+HTTP/2 implemented on UDP. Because TCP is implemented at the
lowest levels of machinery (operating systems, routing firmware), making
changes to TCP is next to impossible given the amount of upgrades that would
need to occur. Since QUIC is built on top of UDP, it suffers from no such
limitations and can be integrated into end host applications.
DNS:
Domain Name System (DNS) is a hostname for IP address translation service.
DNS is a distributed database implemented in a hierarchy of name servers. It is
an application layer protocol for message exchange between clients and
servers. It is required for the functioning of the Internet. It is very difficult to
find out the IP address associated with a website because there are millions of
websites and with all those websites we should be able to generate the IP
address immediately, there should not be a lot of delays for that to happen
organization of the database is very important.
PRACTICAL 2
AIM: Explore socket programming in any language. Write a
Program to encrypt your given plaintext into ciphertext using
socket
Server:
import socket
HOST = "127.0.0.1"
PORT = 65432
with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:
s.bind((HOST,PORT))
s.listen()
conn, addr = s.accept()
with conn:
print(f"Connected by {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
Output:
Client:
import socket
HOST = "127.0.0.1"
PORT = 65432
print(f"Received {data!r}")
Output:
AIM: Write code for encryption and decryption of message using
Socket Programming
Server:
import socket
def ecrypt(text,shift):
result=""
for i in range(len(text)):
char=text[i]
if(char.isalpha()):
if(char.isupper()):
result+=chr((ord(char)+shift-65)%26 + 65)
if(char.islower()):
result+=chr((ord(char)+shift-97)%26 + 97)
else:
result+=char
return result
s=socket.socket()
port=12347
s.bind(('127.0.0.2',port))
print("Socket binded to %s"%(port))
s.listen(5)
while True:
c,addr=s.accept()
print("got connection from",addr)
k=input("Enter the plaintext:")
shift=3
encrypted_text=ecrypt(k,shift)
print("The encrypted text is:",encrypted_text)
c.send(encrypted_text.encode())
c.close()
break
Output:
Client:
import socket
def decrypt(text,shift):
result=""
for i in range(len(text)):
char=text[i]
if(char.isalpha()):
if(char.isupper()):
result+=chr((ord(char)-shift-65)%26 + 65)
if(char.islower()):
result+=chr((ord(char)-shift-97)%26 + 97)
else:
result+=char
return result
import socket
s=socket.socket()
port=12347
s.connect(('127.0.0.2',port))
text=s.recv(1024).decode()
print("The text before decryption is:",text)
shift=3
decrypted_text=decrypt(text,shift)
print("The decrypted text is",decrypted_text)
s.close()
Ouput:
PRACTICAL - 3
Code:
import random
e = random.randrange(1, phi)
while gcd(e, phi) != 1:
e = random.randrange(1, phi)
d = mod_inverse(e, phi)
return ((n, e), (n, d))
if __name__ == '__main__':
p = 61 # Replace with a prime number
q = 53 # Replace with another prime number
public_key, private_key = generate_keypair(p, q)
Output:
PRACTICAL - 4
Symmetric Encryption
Code:
key = Fernet.generate_key()
cipher = Fernet(key)
plaintext = b"Sidhi Gupta UE218099"
cipher_text = cipher.encrypt(plaintext)
decrypted_text = cipher.decrypt(cipher_text)
print("Plaintext:", plaintext)
print("Cipher Text:", cipher_text)
print("Decrypted Text:", decrypted_text)
Output:
Asymmetric Encryption
Code:
public_key = private_key.public_key()
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
ciphertext = public_key.encrypt(
plaintext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
private_key = serialization.load_pem_private_key(private_pem, password=None)
decrypted_text = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
print("Plaintext:", plaintext)
print("Ciphertext:", ciphertext)
print("Decrypted Text:", decrypted_text)
Output:
HASHING:
Server :
import hashlib
import socket
host = '127.0.0.1'
port = 12345
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen(1)
print(f"Server listening on {host}:{port}")
conn, addr = server_socket.accept()
print(f"Connection from {addr}")
data = conn.recv(1024)
received_message, received_hash = data.split(b'#')
hash_function = hashlib.sha256()
hash_function.update(received_message)
computed_hash = hash_function.digest()
if computed_hash == received_hash:
print("Hash verification successful.")
print("Received Message:", received_message.decode())
else:
print("Hash verification failed!")
conn.close()
Output:
Client:
import hashlib
import socket
host = '127.0.0.1'
port = 12345
hash_function = hashlib.sha256()
hash_function.update(message.encode())
message_hash = hash_function.digest()
client_socket.close()
PRACTICAL -5
AIM: Design a secure messaging system having confidentiality,
integrity and authentication. You are required to send a
message from client to server as well as server to client with
symmetric encryption done at the sender as well you are to
attach digital signature with the message at the sender. The
receiver needs to verify the digital signature, you are to assume
that the public key of receiver is known to sender and public
key of sender is known to receiver. in the first program
symmetric key are also known sender and reciever and in next
program you need to send and receive symmetric key also.
Client Side:
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
import hashlib
# Send ciphertext, tag, nonce, and signature to the server (you would need to implement
your communication method)
server.send(ciphertext)
server.send(tag)
server.send(nonce)
server.send(signature)
Server Side:
from Crypto.Cipher import AES
from Crypto.Signature import PKCS1_v1_5
# Verify the signature using the client's public key
verifier = PKCS1_v1_5.new(client_public_key)
if verifier.verify(message_hash, signature):
print("Signature is valid. Proceed with decryption and processing.")
cipher = AES.new(shared_symmetric_key, AES.MODE_EAX, nonce=nonce)
message = cipher.decrypt_and_verify(ciphertext, tag)
print("Received message:", message.decode())
else:
print("Signature is not valid. Reject the message.")
Output:
Practical 6
AIM: Create a public key certificate using OpenSSL and fetch
keys from the certificate.
Code:
import datetime
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
Code:
from Crypto.Cipher import DES
import secrets
def pad_text(text):
while len(text) % 8 != 0:
text += b' '
return text
def des_encrypt(key,plaintext):
plaintext = pad_text(plaintext)
cipher = DES.new(key,DES.MODE_ECB)
ciphertext = cipher.encrypt(plaintext)
return ciphertext
def des_decrypt(key,ciphertext):
cipher = DES.new(key,DES.MODE_ECB)
decrypted_text = cipher.decrypt(ciphertext)
return decrypted_text
if __name__ == '__main__':
des_key = secrets.token_bytes(8)
plaintext = b"Sidhi Gupta UE218099"
encrypted_data = des_encrypt(des_key,plaintext)
print("Encrypted: ",encrypted_data)
decrypted_data = des_encrypt(des_key,encrypted_data)
print("Decrypted: ",decrypted_data.decode('utf-8').rstrip())
Output:
Code:
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
def pad_text(text):
while len(text) % 8 != 0:
text += b' '
return text
if __name__ == '__main__':
des_key = get_random_bytes(8)
iv = get_random_bytes(8)
plaintext = b"Sidhi Gupta UE218099"
encrypted_data = des_encrypt(des_key, plaintext, iv)
print("Encrypted: ", encrypted_data)
decrypted_data = des_decrypt(des_key, encrypted_data, iv)
print("Decrypted: ", decrypted_data.decode('utf-8').rstrip())
Output: