Network And Information Security
Practical 05
Aim :- Write a program to implement Caesar Cipher.
Requirements:
• Computer system with i5 Intel processor having 8 GB RAM and 1 TB Hard-disk
• Operating system: - Windows
Minimum Theoretical Background:
The Caesar Cipher is one of the simplest and oldest encryption techniques, named after Julius Caesar
who used it for his military correspondence. It's a type of substitution cipher where each letter in the
message is replaced by a different letter a fixed number of positions down the alphabet.
Here's how it works:
Shift value: You choose a number, called the shift value, which determines how many positions each
letter will be moved down the alphabet. For example, with a shift value of 3, "A" becomes "D", "B"
becomes "E", and so on.
Encryption: To encrypt a message, you simply replace each letter with the letter that is the specified
number of positions down the alphabet.
Decryption: To decrypt the message, you shift the letters back up the alphabet by the same number of
positions.
For instance, with a shift value of 1:
• Plaintext: "HELLO"
• Ciphertext: "IFMMP"
While the Caesar Cipher is easy to understand and implement, it's also very weak and easily broken.
This is because there are only a limited number of possible shifts (26, for the number of letters in the
alphabet), and someone trying to crack the code can simply try each one until they find the message
that makes sense.
Modern Applications:
• Although not used for serious cryptography due to its weaknesses, the Caesar Cipher still has
some applications in educational contexts to introduce basic cryptographic concepts.
• It can also be used for simple text-scrambling games or puzzles.
Here's the algorithm for the Caesar Cipher:
1. Input:
• Plaintext: The message you want to encrypt (a string of characters).
• Shift value (k): An integer value representing the number of positions each letter will be shifted
in the alphabet (positive for encryption, negative for decryption).
2. Encryption:
1. Iterate over each character in the plaintext:
o Check if the character is alphabetic (uppercase or lowercase).
Network And Information Security
o For uppercase letters (A-Z):
▪ Subtract the character's ASCII code (ord(char)) by the value of 'A' (65).
▪ Add the shift value (k) to the result.
▪ Apply the modulo operation by 26 ((result + k) % 26) to ensure the result stays
within the alphabet range (0-25).
▪ Add the value of 'A' (65) back to the result to convert it back to an uppercase ASCII
code.
▪ Convert the ASCII code back to a character using chr(result).
o For lowercase letters (a-z):
▪ Follow the same steps as for uppercase letters, but subtracting and adding the
value of 'a' (97) instead of 'A' (65).
o For non-alphabetic characters:
▪ Keep the character unchanged.
2. Append the processed character to the ciphertext string.
3. Output:
• Ciphertext: The encrypted message (a string of characters).
4. Decryption:
1. Follow the same steps as for encryption, but use the negative of the shift value (-k) to shift the
letters back in the alphabet.
Here's a Python program implementing the Caesar Cipher for both encryption and decryption:
def caesar_cipher(text, shift, mode):
result = ""
for char in text:
if char.isalpha():
# Convert character to uppercase for easier handling
char = char.upper()
new_ord = ord(char) + shift
# Handle wrapping around the alphabet
new_ord = (new_ord - ord('A')) % 26 + ord('A')
# Convert back to lowercase if the original character was lowercase
result += chr(new_ord) if char.islower() else chr(new_ord)
else:
# Keep non-alphabetic characters unchanged
result += char
return result
# Get user input
text = input("Enter your text: ")
shift = int(input("Enter the shift value: "))
mode = input("Enter 'encrypt' or 'decrypt': ")
# Check for valid mode
Network And Information Security
if mode not in ("encrypt", "decrypt"):
print("Invalid mode. Please enter 'encrypt' or 'decrypt'.")
exit()
# Perform encryption or decryption
if mode == "encrypt":
result = caesar_cipher(text, shift, mode)
print("Encrypted text:", result)
else:
result = caesar_cipher(text, -shift, mode) # Use negative shift for decryption
print("Decrypted text:", result)
Output :-
Conclusion :- This program defines a function caesar_cipher that takes the text, shift value, and mode
(encrypt or decrypt) as arguments. It iterates through each character, checks if it's alphabetic, and then
shifts it based on the mode and shift value. The program also handles wrapping around the alphabet
and maintaining the case of the original characters.
Dated signature of
Marks Obtained
Teacher
Process Product
Total (25)
Related (10) Related (15)
Network And Information Security
Practical 06
Aim :- Write a program to implement Vernam Cipher.
Requirements:
• Computer system with i5 Intel processor having 8 GB RAM and 1 TB Hard-disk
• Operating system: - Windows
Minimum Theoretical Background:
The Vernam Cipher, also known as the One-Time Pad (OTP), is a symmetric stream cipher that offers
theoretically unbreakable encryption under specific conditions. Here's a breakdown of the key points:
Functionality:
• It operates on the binary level of the message, treating each character (or unit of information) as
a sequence of bits (0s and 1s).
• A keystream, which is a random sequence of bits, is used to combine with the message
(plaintext) using the exclusive OR (XOR) operation. This operation flips the bits whenever the
corresponding bits in the message and keystream are different.
• Mathematically: Ciphertext = Plaintext XOR Keystream
• Decryption involves performing the XOR operation again with the same keystream: Plaintext =
Ciphertext XOR Keystream
Security:
• The critical aspect of the Vernam Cipher's security lies in the keystream. It must be:
o Truly random: Each bit in the keystream must be unpredictable and independent of the
others.
o As long as the message (plaintext): The keystream cannot be reused for multiple
messages, as this would compromise security.
• If these conditions are met, the Vernam Cipher is provably secure according to the Shannon's
information theory. This means that an attacker with unlimited resources and time cannot
statistically distinguish the ciphertext from random noise, making it unbreakable.
Limitations:
• Key management: Generating and distributing truly random keys as long as the message is a
significant challenge. In practice, achieving perfect randomness is difficult, and weaknesses in
key generation can compromise security.
• Scalability: It's impractical for large-scale communication due to the key management overhead.
Applications:
• Despite the limitations, the Vernam Cipher has historical significance in military and diplomatic
communication due to its theoretical unbreakability.
• It can be used for masking highly sensitive information in specific scenarios where secure key
management is possible.
Network And Information Security
Here's the algorithm for the Vernam Cipher:
1. Input:
• Plaintext: The message to encrypt or decrypt (binary string).
• Keystream: A random sequence of bits as long as the message (binary string). This is the crucial
element for security and should only be used once and be truly random.
2. Encryption:
1. Convert the plaintext message to a binary string.
2. Perform a bitwise XOR (exclusive OR) operation on the message bits with the corresponding
keystream bits.
o For each bit position in the message and keystream:
▪ If both bits are the same (0 XOR 0 or 1 XOR 1), the result is 0.
▪ If the bits are different (0 XOR 1 or 1 XOR 0), the result is 1.
3. Convert the resulting binary string back to the encrypted message format (e.g., text).
3. Output:
• Ciphertext: The encrypted message (in the same format as the original message, but with the
content scrambled based on the keystream).
4. Decryption:
1. Convert the ciphertext back to a binary string.
2. Perform the same bitwise XOR operation on the ciphertext bits with the corresponding
keystream bits. This effectively reverses the encryption process and recovers the original
message.
3. Convert the resulting binary string back to the original message format (e.g., text).
Here's a Python program implementing the Vernam Cipher for both encryption and decryption:
def vernam_cipher(message, key, mode):
if len(message) != len(key):
raise ValueError("Message and key must have the same length.")
if mode not in ("encrypt", "decrypt"):
raise ValueError("Invalid mode. Please enter 'encrypt' or 'decrypt'.")
result = ""
for i in range(len(message)):
if mode == "encrypt":
result += str(int(message[i]) ^ int(key[i]))
else:
result += str(int(message[i]) ^ int(key[i]))
return result
Network And Information Security
# Get user input
message = input("Enter your message (binary string): ")
key = input("Enter the keystream (binary string, same length as message): ")
# Check input validity
if not all(char in "01" for char in message) or not all(char in "01" for char in
key):
print("Invalid input. Please enter binary strings (0s and 1s only).")
exit()
# Perform encryption or decryption
mode = input("Enter 'encrypt' or 'decrypt': ")
try:
result = vernam_cipher(message, key, mode)
print(f"{mode.capitalize()}d result:", result)
except ValueError as e:
print(e)
Output :-
Conclusion :- This program defines a function caesar_cipher that takes the text, shift value, and mode
(encrypt or decrypt) as arguments. It iterates through each character, checks if it's alphabetic, and then
shifts it based on the mode and shift value. The program also handles wrapping around the alphabet
and maintaining the case of the original characters.
Dated signature of
Marks Obtained
Teacher
Process Product
Total (25)
Related (10) Related (15)
Network And Information Security
Practical 07
Aim :- Create and verify Hash code fir given text.
Requirements:
• Computer system with i5 Intel processor having 8 GB RAM and 1 TB Hard-disk
• Operating system: - Windows
Minimum Theoretical Background:
A hash code, also simply called a hash, is a fixed-length numeric value derived from an input, such as a
string of text, a file, or even an object in computer science. It acts like a digital fingerprint that uniquely
identifies the input, but doesn't reveal the original data itself.
Here are some key aspects of hash codes:
Functionality:
• Hashing algorithms take an input of variable size and compress it into a fixed-length output,
typically much smaller than the original input.
• The goal is to create a unique hash code for each unique input, but collisions can occur where
different inputs generate the same hash code. However, good hashing algorithms minimize the
probability of collisions.
Applications:
• Hash codes are widely used in various applications, including:
o Data integrity checks: They can ensure that data hasn't been altered during transmission
or storage. If the calculated hash code doesn't match the expected hash code, it indicates
a potential modification.
o Hash tables: These data structures use hash codes to efficiently store and retrieve
information based on key-value pairs.
o Password storage: Hashes are often used to store passwords securely. Instead of storing
the actual password, its hash is saved. When a user attempts to log in, the entered
password is hashed and compared to the stored hash. This approach protects the original
password from being retrieved even if the database is compromised.
Properties:
• Deterministic: Given the same input, a good hashing algorithm will always produce the same
hash code.
• Avalanche effect: Small changes in the input should result in significant changes in the hash code.
• Collision resistance: It should be computationally difficult to find different inputs that generate
the same hash code.
Limitations:
• Collisions: As mentioned earlier, collisions can occur, although the probability should be very low
for a well-designed hashing algorithm.
• Non-reversibility: You cannot retrieve the original data from the hash code itself.
Network And Information Security
Real-world Examples:
• BitTorrent: Uses hash codes to verify the integrity of downloaded file parts.
• Git: Relies on hash codes to track changes and maintain version control of code repositories.
• Blockchains: Utilize hash codes to cryptographically link blocks together, forming the core
structure of blockchain technology.
Here's the algorithm for the Hash Code:
1. Preprocessing (Optional):
• This step might involve actions like converting the input data to a specific format (e.g., converting
text to lowercase) or padding the data to a fixed length if necessary for the chosen algorithm.
2. Divide into Chunks:
• The input data (message, file, etc.) is often divided into smaller, fixed-size chunks.
3. Compression and Transformation:
• Each chunk is processed individually using a series of mathematical operations designed to:
o Compress the data: Reduce the size of the data significantly compared to the original
input.
o Introduce avalanche effect: Small changes in the input should significantly alter the
output hash code.
o Ensure collision resistance: Minimize the probability of different inputs generating the
same hash code.
4. Chaining (Optional):
• Some algorithms employ a chaining technique where the output from processing one chunk is
combined with the result of the previous chunk, potentially using another mathematical
operation. This creates a dependency between the processing of different chunks, potentially
influencing the final hash code.
5. Finalization:
• After processing all chunks, a final operation is performed to produce the final fixed-length hash
code.
Popular Hashing Algorithms:
• MD5: An older algorithm, considered less secure due to known vulnerabilities.
• SHA-1: Another widely used algorithm, but also with security concerns.
• SHA-256 (and variants like SHA-384, SHA-512): A family of secure and recommended hashing
algorithms for various applications.
• BLAKE2: Another family of secure and efficient hashing algorithms.
Network And Information Security
Here's an example of creating and verifying a hash code for a given text in Python:
from hashlib import sha256
def create_hash(text):
hasher = sha256()
hasher.update(text.encode()) # Convert text to bytes for hashing
return hasher.hexdigest()
def verify_hash(text, hash_code):
return create_hash(text) == hash_code
# Example usage
text = "This is some text to hash."
hash_code = create_hash(text)
print("Original text:", text)
print("SHA-256 hash:", hash_code)
# Verification
verified = verify_hash(text, hash_code)
print("Hash code verified:", verified)
# Tampering the text and re-verifying
tampered_text = text + " (modified)"
verified = verify_hash(tampered_text, hash_code)
print("Hash code verified for tampered text:", verified)
Output :-
This code defines two functions:
• create_hash: Takes text as input and returns the SHA-256 hash code as a hexadecimal string.
• verify_hash: Takes text and a hash code as input and returns True if the hash code matches the
SHA-256 hash of the text, False otherwise.
The example demonstrates how to use these functions to create a hash code, verify it, and show how a
change in the text leads to a different hash code, highlighting the verification functionality.
Network And Information Security
Important notes:
• This example uses SHA-256, which is a commonly used and secure hashing algorithm. However,
there are other hashing algorithms available, each with its own characteristics and security
considerations.
• Hash codes are not reversible, meaning you cannot retrieve the original text from the hash code.
• Tampering with the original text even slightly will result in a completely different hash code,
making it a valuable tool for verifying data integrity.
Conclusion :-
• This example uses SHA-256, which is a commonly used and secure hashing algorithm. However,
there are other hashing algorithms available, each with its own characteristics and security
considerations.
• Hash codes are not reversible, meaning you cannot retrieve the original text from the hash code.
• Tampering with the original text even slightly will result in a completely different hash code,
making it a valuable tool for verifying data integrity.
Dated signature of
Marks Obtained
Teacher
Process Product
Total (25)
Related (10) Related (15)
Network And Information Security
Practical 08
Aim :- Write a program to implement Rail fence technique.
Requirements:
• Computer system with i5 Intel processor having 8 GB RAM and 1 TB Hard-disk
• Operating system: - Windows
Minimum Theoretical Background:
The Rail Fence Cipher, also known as the Zigzag Cipher, is a simple transposition cipher used for
encryption. It derives its name from the way the message is written during the encryption process,
resembling a series of rails on a fence. Here's a breakdown of the technique:
Encryption:
1. Choose a number of rails (key): This can be any number, but the more rails used, the more
complex the cipher becomes.
2. Write the message diagonally down the rails: Start at the top rail and write the first letter of the
message. Then, move diagonally down to the next rail (or wrap around to the top if reaching the
bottom) and write the second letter. Continue in this zigzag pattern until you reach the bottom
rail, then move diagonally up to the next rail (or wrap around to the bottom if reaching the top)
and write the next letter. Repeat this process until the entire message is written.
3. Read the message off the rails: Once all the letters are written, disregard the rails and read the
message horizontally, row by row, from top to bottom. This scrambled message is the ciphertext.
Decryption:
1. Knowing the number of rails (key) is crucial: You need to know the same number of rails used
for encryption to decipher the message.
2. Write empty rails: Draw the same number of empty horizontal lines as the key (number of rails
used in encryption).
3. Fill the rails diagonally: Starting from the top rail, write each letter of the ciphertext onto the rails
in a zigzag pattern, following the same direction as in encryption. Once you reach the bottom rail,
move diagonally up to the next rail and continue writing.
4. Read the message horizontally: After filling all the rails, disregard the rails and read the message
horizontally, row by row, from top to bottom. This reveals the original plaintext message.
Example:
Plaintext: "SECRET MESSAGE" Key: 3 (number of rails)
Encryption:
S E C R E T
E M S S A G
C R E
Ciphertext: SEMCSRA GET
Network And Information Security
Decryption:
S E C R E T
E M S S A G
C R E
Plaintext: SECRET MESSAGE
Security:
The Rail Fence Cipher is a weak encryption method and is not secure for serious communication. It can
be easily broken by techniques like frequency analysis, especially with short messages and a limited
number of rails. However, it has historical significance as one of the simplest encryption techniques and
can serve as an educational tool for understanding the principles of cryptography.
Here's the algorithm for the Rail Fence Technique:
1. Input:
• Plaintext: The message to encrypt (a string of characters).
• Key (rails): The number of rails to use (positive integer).
2. Encryption:
1. Initialize an empty list of strings, where each string represents a rail. The length of the list should
be equal to the number of rails (rails).
2. Iterate over each character in the plaintext message:
o Calculate the current row index:
▪ Divide the current character position by the total number of characters and
multiply by the number of rails, taking the floor of the result (floor(i * rails /
len(message))).
o Append the character to the corresponding rail list at the calculated index.
3. Concatenate the strings in the rail list to form the ciphertext.
3. Output:
• Ciphertext: The encrypted message (a string of characters).
4. Decryption:
1. Follow the same steps as for encryption, but instead of appending characters to the rail lists, read
characters from each list sequentially based on the same row index calculation used in
encryption.
2. Concatenate the characters read from the rails to form the decrypted message.
Network And Information Security
Here's a Python program implementing the Rail Fence Cipher for both encryption and decryption:
def rail_fence_cipher(message, rails, mode):
rows = ["" for _ in range(rails)]
row_index = 0
step = 1
if mode == "encrypt":
for char in message:
rows[row_index] += char
row_index += step
if row_index == 0 or row_index == rails - 1:
step *= -1
elif mode == "decrypt":
for _ in range(len(message)):
for i in range(rails):
if rows[i]:
char = rows[i][0]
rows[i] = rows[i][1:]
break
row_index += step
if row_index == 0 or row_index == rails - 1:
step *= -1
else:
raise ValueError("Invalid mode. Please enter 'encrypt' or 'decrypt'.")
return "".join(rows)
# Example usage
message = "SECRET MESSAGE"
rails = 3
ciphertext = rail_fence_cipher(message, rails, "encrypt")
print("Encrypted message:", ciphertext)
decrypted_message = rail_fence_cipher(ciphertext, rails, "decrypt")
print("Decrypted message:", decrypted_message)
Network And Information Security
Output :-
Conclusion :-
This program defines a function rail_fence_cipher that takes the message, number of rails (key), and
mode (encrypt or decrypt) as arguments. It utilizes lists to represent the rails and iterates through the
message character by character, following the encryption or decryption logic described earlier.
Dated signature of
Marks Obtained
Teacher
Process Product
Total (25)
Related (10) Related (15)