|
|
import streamlit as st
|
|
|
from PIL import Image
|
|
|
import numpy as np
|
|
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
|
from cryptography.hazmat.backends import default_backend
|
|
|
from cryptography.hazmat.primitives import padding
|
|
|
from io import BytesIO
|
|
|
def img_cryptography():
|
|
|
|
|
|
|
|
|
def pad_data(data):
|
|
|
try:
|
|
|
padder = padding.PKCS7(128).padder()
|
|
|
padded_data = padder.update(data) + padder.finalize()
|
|
|
return padded_data
|
|
|
except Exception as e:
|
|
|
raise ValueError(f"Padding Error: {e}")
|
|
|
|
|
|
|
|
|
def unpad_data(data):
|
|
|
try:
|
|
|
unpadder = padding.PKCS7(128).unpadder()
|
|
|
unpadded_data = unpadder.update(data) + unpadder.finalize()
|
|
|
return unpadded_data
|
|
|
except Exception as e:
|
|
|
raise ValueError(f"Unpadding Error: {e}")
|
|
|
|
|
|
|
|
|
def encrypt_image(image_bytes, key):
|
|
|
try:
|
|
|
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
|
|
|
encryptor = cipher.encryptor()
|
|
|
|
|
|
|
|
|
padded_bytes = pad_data(image_bytes)
|
|
|
encrypted_bytes = encryptor.update(padded_bytes) + encryptor.finalize()
|
|
|
return encrypted_bytes
|
|
|
except Exception as e:
|
|
|
raise ValueError(f"Encryption Error: {e}")
|
|
|
|
|
|
|
|
|
def decrypt_image(encrypted_bytes, key):
|
|
|
try:
|
|
|
cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
|
|
|
decryptor = cipher.decryptor()
|
|
|
decrypted_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize()
|
|
|
|
|
|
|
|
|
unpadded_bytes = unpad_data(decrypted_bytes)
|
|
|
return unpadded_bytes
|
|
|
except ValueError as e:
|
|
|
raise ValueError(f"Decryption Error: Invalid padding or incorrect key - {e}")
|
|
|
except Exception as e:
|
|
|
raise ValueError(f"Decryption Error: {e}")
|
|
|
|
|
|
|
|
|
st.title("Image Encryption and Decryption using AES")
|
|
|
|
|
|
|
|
|
key_length = st.selectbox("Choose AES key length:", [16, 24, 32])
|
|
|
|
|
|
|
|
|
def generate_key(key_input, length):
|
|
|
try:
|
|
|
key = key_input.encode('utf-8')
|
|
|
if len(key) < length:
|
|
|
|
|
|
key = key.ljust(length, b'\0')
|
|
|
elif len(key) > length:
|
|
|
|
|
|
key = key[:length]
|
|
|
return key
|
|
|
except Exception as e:
|
|
|
raise ValueError(f"Key Generation Error: {e}")
|
|
|
|
|
|
|
|
|
key_input = st.text_input(f"Enter AES encryption key (up to {key_length} characters):", type="password")
|
|
|
|
|
|
|
|
|
if key_input and key_length:
|
|
|
key = generate_key(key_input, key_length)
|
|
|
else:
|
|
|
st.warning(f"Please enter a key of length {key_length} characters for encryption and decryption.")
|
|
|
key = None
|
|
|
|
|
|
|
|
|
col1, col2 = st.tabs(["Encryption","Decryption"])
|
|
|
|
|
|
|
|
|
with col1:
|
|
|
st.header("Encryption")
|
|
|
|
|
|
|
|
|
uploaded_file = st.file_uploader("Choose an image to encrypt...", type=["jpg", "jpeg", "png"])
|
|
|
|
|
|
if uploaded_file is not None and key:
|
|
|
|
|
|
image = Image.open(uploaded_file)
|
|
|
st.image(image, caption="Original Image", use_column_width=True)
|
|
|
|
|
|
if st.button("Encrypt"):
|
|
|
|
|
|
image_bytes = BytesIO()
|
|
|
image.save(image_bytes, format="PNG")
|
|
|
image_bytes = image_bytes.getvalue()
|
|
|
|
|
|
|
|
|
encrypted_bytes = encrypt_image(image_bytes, key)
|
|
|
|
|
|
|
|
|
encrypted_bin_file = "encrypted_image.bin"
|
|
|
with open(encrypted_bin_file, "wb") as f:
|
|
|
f.write(encrypted_bytes)
|
|
|
|
|
|
|
|
|
|
|
|
encrypted_array = np.frombuffer(encrypted_bytes, dtype=np.uint8)
|
|
|
padded_array = np.zeros(image.size[0] * image.size[1], dtype=np.uint8)
|
|
|
padded_array[:len(encrypted_array)] = encrypted_array[:len(padded_array)]
|
|
|
|
|
|
|
|
|
encrypted_image_array = padded_array.reshape(image.size[1], image.size[0])
|
|
|
encrypted_image = Image.fromarray(encrypted_image_array, mode="L")
|
|
|
encrypted_image_file = "encrypted_image.png"
|
|
|
encrypted_image.save(encrypted_image_file, format="PNG")
|
|
|
|
|
|
|
|
|
st.success("Image Encrypted Successfully!")
|
|
|
st.download_button(label="Download Encrypted BIN File", data=encrypted_bytes, file_name="encrypted_image.bin")
|
|
|
st.download_button(label="Download Encrypted PNG File", data=open(encrypted_image_file, "rb").read(), file_name="encrypted_image.png")
|
|
|
st.image(encrypted_image, caption="Encrypted Image (PNG)", use_column_width=True)
|
|
|
|
|
|
|
|
|
|
|
|
with col2:
|
|
|
st.header("Decryption")
|
|
|
|
|
|
|
|
|
encrypted_file = st.file_uploader("Upload an encrypted file to decrypt (.bin only)...", type=["bin"])
|
|
|
|
|
|
if encrypted_file is not None and key:
|
|
|
try:
|
|
|
|
|
|
encrypted_bytes = encrypted_file.read()
|
|
|
|
|
|
|
|
|
decrypted_bytes = decrypt_image(encrypted_bytes, key)
|
|
|
|
|
|
|
|
|
decrypted_image = Image.open(BytesIO(decrypted_bytes))
|
|
|
st.image(decrypted_image, caption="Decrypted Image", use_column_width=True)
|
|
|
|
|
|
|
|
|
decrypted_image_file = "decrypted_image.jpg"
|
|
|
decrypted_image.save(decrypted_image_file, format="JPEG")
|
|
|
|
|
|
st.success("Image Decrypted Successfully!")
|
|
|
st.download_button(label="Download Decrypted Image (JPG)", data=open(decrypted_image_file, "rb").read(), file_name="decrypted_image.jpg")
|
|
|
|
|
|
except ValueError as e:
|
|
|
st.error(f"Error in decryption: {e}. This may indicate mismatched padding or incorrect decryption keys.")
|
|
|
except Exception as e:
|
|
|
st.error(f"Unexpected error: {e}")
|
|
|
|