File size: 7,463 Bytes
319dbb7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
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():

    # Function to add padding to the image bytes
    def pad_data(data):
        try:
            padder = padding.PKCS7(128).padder()  # AES block size is 128 bits (16 bytes)
            padded_data = padder.update(data) + padder.finalize()
            return padded_data
        except Exception as e:
            raise ValueError(f"Padding Error: {e}")

    # Function to remove padding after decryption
    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}")

    # Function to encrypt image using AES with a user-provided key
    def encrypt_image(image_bytes, key):
        try:
            cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
            encryptor = cipher.encryptor()

            # Pad the image bytes before encryption
            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}")

    # Function to decrypt image using AES with a user-provided key
    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()

            # Remove padding after decryption
            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}")

    # Streamlit user interface
    st.title("Image Encryption and Decryption using AES")

    # Option for selecting key length
    key_length = st.selectbox("Choose AES key length:", [16, 24, 32])

    # Function to generate the AES key based on user input
    def generate_key(key_input, length):
        try:
            key = key_input.encode('utf-8')
            if len(key) < length:
                # Pad the key with null bytes if it's shorter than the selected length
                key = key.ljust(length, b'\0')
            elif len(key) > length:
                # Truncate the key if it's longer than the selected length
                key = key[:length]
            return key
        except Exception as e:
            raise ValueError(f"Key Generation Error: {e}")

    # Input for AES Key
    key_input = st.text_input(f"Enter AES encryption key (up to {key_length} characters):", type="password")

    # Ensure the key is of the correct length after processing
    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

    # Create two columns for encryption and decryption sections
    col1, col2 = st.tabs(["Encryption","Decryption"])

    # ENCRYPTION SECTION (Left Column)
    with col1:
        st.header("Encryption")

        # Option to upload image for encryption
        uploaded_file = st.file_uploader("Choose an image to encrypt...", type=["jpg", "jpeg", "png"])

        if uploaded_file is not None and key:
            # Display the original image
            image = Image.open(uploaded_file)
            st.image(image, caption="Original Image", use_column_width=True)

            if st.button("Encrypt"):
                # Convert image to bytes for encryption
                image_bytes = BytesIO()
                image.save(image_bytes, format="PNG")
                image_bytes = image_bytes.getvalue()

                # Encrypt the image bytes
                encrypted_bytes = encrypt_image(image_bytes, key)

                # Save the encrypted bytes as a .bin file
                encrypted_bin_file = "encrypted_image.bin"
                with open(encrypted_bin_file, "wb") as f:
                    f.write(encrypted_bytes)

                # To visualize encrypted data, truncate or pad it to match the original size
                # Use numpy to create a grayscale view of the encrypted data
                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)]

                # Reshape to match image dimensions and visualize as a grayscale image
                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")

                # Success message and download buttons
                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)


    # DECRYPTION SECTION (Right Column)
    with col2:
        st.header("Decryption")

        # Option to upload encrypted file for decryption (.bin only)
        encrypted_file = st.file_uploader("Upload an encrypted file to decrypt (.bin only)...", type=["bin"])

        if encrypted_file is not None and key:
            try:
                # Read encrypted binary data
                encrypted_bytes = encrypted_file.read()

                # Decrypt the image
                decrypted_bytes = decrypt_image(encrypted_bytes, key)

                # Convert decrypted bytes back to image
                decrypted_image = Image.open(BytesIO(decrypted_bytes))
                st.image(decrypted_image, caption="Decrypted Image", use_column_width=True)

                # Save decrypted image as JPG
                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}")