Index
Index
DECRYPTION CODE:
def caesar_decrypt(ciphertext, shift):
return caesar_encrypt(ciphertext, -shift)
decrypted_text = caesar_decrypt(encrypted_text, shift)
print(f"Decrypted: {decrypted_text}")
TRANSPOSITION CIPHER
ENCRYPTION CODE:
def columnar_encrypt(plaintext, key):
# Ensure the plaintext length is a multiple of the key by padding with spaces if necessary
padding_length = (key - len(plaintext) % key) % key
plaintext_padded = plaintext + ' ' * padding_length
DECRYPTION CODE:
def columnar_decrypt(ciphertext, key):
n = len(ciphertext) // key
grid = [''] * key
index = 0
for i in range(key):
grid[i] = ciphertext[index:index + n]
index += n
decrypted = ''.join([''.join(col) for col in zip(*grid)])
return decrypted
q = random.getrandbits(bitlength)
n=p*q
phi = (p - 1) * (q - 1)
e = random.randrange(1, phi)
g = gcd(e, phi)
while g != 1:
e = random.randrange(1, phi)
g = gcd(e, phi)
d = mod_inverse(e, phi)
return ((e, n), (d, n))
def encrypt(public_key, plaintext):
e, n = public_key
cipher = [pow(ord(char), e, n) for char in plaintext]
return cipher
def decrypt(private_key, ciphertext):
d, n = private_key
plain = [chr(pow(char, d, n)) for char in ciphertext]
return ''.join(plain)
# Example usage:
bitlength = 8
public_key, private_key = generate_keypair(bitlength)
message = "Hello, RSA!"
encrypted_message = encrypt(public_key, message)
print (message)
print("Encrypted:", encrypted_message)
decrypted_message = decrypt(private_key, encrypted_message)
PRACTICAL 3
To implement Message Authentication Codes (MACs) for ensuring data integrity and authenticity,
you can follow these two steps:
1. Generating a MAC: A MAC is a tag or signature appended to the message, which is generated
using a secret key. It ensures the message’s authenticity and integrity.
2. Verifying a MAC: When the message is received, the recipient regenerates the MAC using the
same key and compares it with the one received to verify integrity.
Below are the steps to implement MAC generation and verification using Python’s hmac library:
import hmac
import hashlib
def generate_mac(key, message):
# Create a new HMAC object using the provided key and SHA-256 as the hashing algorithm
hmac_obj = hmac.new(key, message, hashlib.sha256)
# Return the generated MAC (in hexadecimal form for better readability)
return hmac_obj.hexdigest()
# Example usage:
key = b'secret_key'
message = b'This is a secure message'
mac = generate_mac(key, message)
print("Generated MAC:", mac)
# Example usage:
received_mac = mac # From Step 1
is_valid = verify_mac(key, message, received_mac)
print("Is the MAC valid?", is_valid)
Explanation:
hmac.new(key, message, hashlib.sha256): This creates a new HMAC object using the provided key
and message with SHA-256 as the hashing algorithm.
hmac.compare_digest(a, b): This method securely compares two MACs to avoid timing attacks.
Conclusion:
The MAC generation and verification ensures that any change in the message will lead to a
mismatch during verification, thus detecting unauthorized modifications.
PRACTICAL 4
Digital Signatures: Implement digital signature algorithms such as RSA-based signatures, and
verify the integrity and authenticity of digitally signed messages.
Digital signatures use cryptographic algorithms to ensure the integrity and authenticity of a
message. One popular algorithm for digital signatures is RSA. The process involves signing a
message with a private key and verifying it with the corresponding public key. Below is a simple
implementation of RSA-based digital signatures in Python using the cryptography library.
# Example usage
message = b"Secure message"
signature = sign_message(private_key, message)
print("Signature:", signature.hex())
To verify a digital signature, we use the public key. This ensures that the message was signed by the
corresponding private key.
# Example usage
is_valid = verify_signature(public_key, message, signature)
print("Is the signature valid?", is_valid)
Explanation:
Private Key: Used to sign messages. Only the signer should possess this key.
Public Key: Used to verify the signature. It is shared with anyone who needs to verify the message.
PSS (Probabilistic Signature Scheme): A padding scheme for RSA signatures, providing security
against attack.
PRACTICAL 5
Key Exchange using Diffie-Hellman: Implement the Diffie-Hellman key exchange algorithm to
securely exchange keys between two entities over an insecure network.
The Diffie-Hellman key exchange algorithm allows two entities to securely exchange cryptographic
keys over an insecure network. Each party generates a public and private key, exchanges the public
key, and derives a shared secret key that can be used for encryption or other cryptographic
purposes.
Below is a Python implementation of the Diffie-Hellman key exchange using the cryptography
library.
Step 1: Install the cryptography library
If you don't have the library installed, you can install it using:
pip install cryptography
def generate_dh_keys():
# Generate Diffie-Hellman parameters (this can be shared between parties)
parameters = dh.generate_parameters(generator=2, key_size=2048, backend=default_backend())
# Generate a private key for a party
private_key = parameters.generate_private_key()
# Obtain the public key corresponding to the private key
public_key = private_key.public_key()
return private_key, public_key, parameters
# Example usage (for party A):
private_key_A, public_key_A, parameters = generate_dh_keys()
return derived_key
# Example usage:
derived_key_A = derive_key(shared_secret_A)
print("Derived Key (Party A):", derived_key_A.hex())
How It Works:
1. Key Generation: Both parties (A and B) generate a private key and a corresponding public key.
2. Public Key Exchange: Each party sends their public key to the other.
3. Shared Secret Calculation: Each party uses their own private key and the other party's public
key to compute a shared secret
4. Key Derivation: The shared secret can be used directly or passed through a key derivation
function to produce a key for encryption.
Conclusion:
The Diffie-Hellman key exchange ensures that even if a third party intercepts the public keys, they
cannot compute the shared secret without access to the private keys. This allows secure key
exchange over an insecure channel.
Let me know if you need further clarification or enhancements!
PRACTICAL 6
IPsec (Internet Protocol Security) is a protocol suite that provides secure communication over IP
networks. It ensures confidentiality, integrity, and authenticity of data transmitted between
network devices. IPsec can be configured in two main modes: Transport Mode and Tunnel Mode.
Here, we’ll outline how to configure IPsec on network devices like routers or firewalls for secure
communication using basic concepts, and we'll focus on configuring IPsec in Tunnel Mode, which is
often used for site-to-site VPNs.
The configuration for Router 2 is very similar to Router 1, except with reversed IP addresses for the
peer and interesting traffic.
1. Configure ISAKMP (IKE Phase 1)
Router(config)# crypto isakmp policy 10
Router(config-isakmp)# encryption aes 256
Router(config-isakmp)# hash sha256
Router(config-isakmp)# authentication pre-share
Router(config-isakmp)# group 14
Router(config-isakmp)# lifetime 86400
Web Security with SSL/TLS:Configure and implement secure web communication using SSL/TLS
protocols, including certificate management and secure session establishment.
SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are cryptographic protocols
designed to secure communication over a network, typically for web traffic. TLS is the successor to
SSL and is considered more secure. Configuring and implementing SSL/TLS for secure web
communication requires enabling these protocols on web servers and managing certificates to
authenticate the server to the client.
# Certbot will ask for domain name and email address for certificate.
2. Edit Nginx Configuration for SSL/TLS: Open the configuration file for your site, typically found
in /etc/nginx/sites-available/your_domain:sudo nano /etc/nginx/sites-available/your_domain
server {
listen 443 ssl;
server_name your_domain.com www.your_domain.com;
ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
3. Edit Apache Configuration for SSL/TLS: Open the virtual host configuration file for your
domain:
sudo nano /etc/apache2/sites-available/your_domain.conf
4. Add SSL Configuration:
Example configuration:
<VirtualHost *:80>
ServerName your_domain.com
Redirect permanent / https://your_domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName your_domain.com
DocumentRoot /var/www/your_domain
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
2. Browser Testing: After configuring SSL/TLS, visit your website using https://your_domain.com.
Check that:
The browser shows the lock icon, indicating a secure connection.
There are no security warnings or certificate errors.
Best Practices for SSL/TLS Configuration:
1. Use Strong Encryption (TLSv1.2 or TLSv1.3): Disable older protocols like SSLv3, TLSv1.0, and
TLSv1.1, as they are vulnerable to attacks.
In Nginx:
ssl_protocols TLSv1.2 TLSv1.3;
In Apache:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
2. HTTP Strict Transport Security (HSTS): This forces browsers to use HTTPS, preventing
HTTP-based attacks.
In Nginx:
add_header Strict-Transport-Security "max-age=31536000" always;
In Apache:
Header always set Strict-Transport-Security "max-age=31536000
3. Enable OCSP Stapling (Optional): OCSP stapling enhances performance by providing faster
certificate validation.
In Nginx:
ssl_stapling on;
ssl_stapling_verify on;
Conclusion:
By configuring SSL/TLS on your web server, you ensure that communication between clients and
your server is encrypted, protecting it from eavesdropping and attacks. With proper certificate
management, secure protocols, and best practices like HSTS, your site will be more secure for users.
PRACTICAL 8
To set up and configure an Intrusion Detection System (IDS) programmatically, you can use Python
combined with a packet sniffing library like Scapy to monitor and analyze network traffic. Below is
a Python-based IDS example that captures network packets and detects potential anomalies such as
port scans and ICMP (ping) floods.
# Detect ICMP flood (many ping requests from the same source)
if pkt.haslayer(ICMP):
print(f"[ALERT] ICMP packet detected from {src_ip}")
# Detect potential port scan by checking if the source IP is sending packets to multiple different
ports
if TCP in pkt:
dst_port = pkt[TCP].dport
print(f"[INFO] TCP packet from {src_ip} to port {dst_port}")
# Print if the packet count exceeds the threshold within the time window
if packet_count[src_ip] > MAX_PACKETS:
print(f"[ALERT] Possible port scan or DoS attack from {src_ip}. Detected
{packet_count[src_ip]} packets in {TIME_WINDOW} seconds.")
# Main function
if __name__ == "__main__":
# Start the reset counter in a separate thread
from threading import Thread
reset_thread = Thread(target=reset_packet_count)
reset_thread.daemon = True
reset_thread.start()
Explanation:
1. Packet Sniffing: The sniff() function from the Scapy library captures live network traffic. The
prn=detect_intrusion parameter tells Scapy to pass each captured packet to the detect_intrusion()
function.
2. Detecting Anomalies:
ICMP Detection: If an ICMP packet is detected, the program logs that a ping request has been sent,
which might indicate a ping flood attack.
Port Scanning: If the same source IP is sending TCP packets to multiple different destination ports
in a short period, it could indicate a port scan.
Threshold-Based Alert: If more than MAX_PACKETS are detected from the same source IP in a
given time window (e.g., 60 seconds), it could indicate a denial-of-service (DoS) or port scan attack.
3. Resetting Packet Counts: A separate thread periodically clears the packet count every 60 seconds
(or any time interval you choose). This ensures the IDS is not permanently triggered by a burst of
traffic
Running the Program
1. Run the Script with Root Privileges: Since sniffing network packets usually requires root access,
you'll need to run the script with elevated privileges. On Linux or macOS: sudo python3
simple_ids.py
2. Monitor the Alerts: As packets are sniffed, the program will print information about ICMP
packets, TCP connections, and alert you when a potential intrusion is detected.
Enhancing the IDS:
You can further extend the functionality of this simple IDS:
1. Add more rules for detecting various types of attacks like SYN floods, DNS attacks, or SQL
injection attempts.
2. Log intrusion attempts to a file instead of just printing to the console.
3. Send alerts via email or integrate with security monitoring tools for better incident response.
4. Use machine learning algorithms to analyze packet patterns for anomalies, improving detection
accuracy.
Conclusion:
This Python-based IDS is a basic demonstration of how you can use Scapy to sniff network traffic
and detect potential security issues like ICMP floods and port scans. For a production environment,
you would likely use more sophisticated tools like Snort, Suricata, or OSSEC, but this gives you an
understanding of the core concepts behind an IDS.