├── requirements.txt ├── Images ├── Image1.jpeg ├── Image2.jpeg ├── Image3.jpeg ├── Image4.jpeg └── Image5.jpeg ├── Project Report.pdf ├── README.md └── final.py /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.13.3 2 | Pillow==9.0.0 3 | pycryptodome==3.12.0 4 | -------------------------------------------------------------------------------- /Images/Image1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aditya-agrawal16/Image-Encryption-and-Decryption-using-AES-algorithm/HEAD/Images/Image1.jpeg -------------------------------------------------------------------------------- /Images/Image2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aditya-agrawal16/Image-Encryption-and-Decryption-using-AES-algorithm/HEAD/Images/Image2.jpeg -------------------------------------------------------------------------------- /Images/Image3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aditya-agrawal16/Image-Encryption-and-Decryption-using-AES-algorithm/HEAD/Images/Image3.jpeg -------------------------------------------------------------------------------- /Images/Image4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aditya-agrawal16/Image-Encryption-and-Decryption-using-AES-algorithm/HEAD/Images/Image4.jpeg -------------------------------------------------------------------------------- /Images/Image5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aditya-agrawal16/Image-Encryption-and-Decryption-using-AES-algorithm/HEAD/Images/Image5.jpeg -------------------------------------------------------------------------------- /Project Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aditya-agrawal16/Image-Encryption-and-Decryption-using-AES-algorithm/HEAD/Project Report.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image-Encryption-and-Decryption-using-AES-algorithm 2 | We have successfully developed a program that encrypts and decrypts the image files accurately. This will help in minimising the problem of data theft and leaks of other sensitive information. The file that we obtained after encryption is very safe and no one can steal data from this file. So, this file can be sent on a network without worrying. At the receiver side, the receiver has code for decrypting the image so that he can get the original image. 3 | 4 | The demo video link is given below:\ 5 | https://youtu.be/4l-pS8uPaJ4 6 | 7 | Recommended to used Linux based machine to avoid unexpected errors.\ 8 | System: Ubuntu18.04.2 on Oracle VM VirtualBox\ 9 | Python version: 2.7.17\ 10 | Libraries used:\ 11 | numpy 1.13.3\ 12 | Pillow 9.0.0\ 13 | pycryptodome 3.12.0\ 14 | Tkinter [linux command: sudo apt-get install python-tk] 15 | -------------------------------------------------------------------------------- /final.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ----------------- Header Files ---------------------# 3 | 4 | from __future__ import division, print_function, unicode_literals 5 | 6 | import sys 7 | import random 8 | import argparse 9 | import logging 10 | from Tkinter import * 11 | import tkFileDialog 12 | import tkMessageBox 13 | import os 14 | import PIL 15 | from PIL import Image 16 | import math 17 | from Crypto.Cipher import AES 18 | import hashlib 19 | import binascii 20 | import numpy as np 21 | 22 | 23 | global password 24 | 25 | def load_image(name): 26 | return Image.open(name) 27 | 28 | # ----------------- Functions for encryption ---------------------# 29 | def prepare_message_image(image, size): 30 | if size != image.size: 31 | image = image.resize(size, Image.ANTIALIAS) 32 | return image 33 | 34 | def generate_secret(size, secret_image = None): 35 | width, height = size 36 | new_secret_image = Image.new(mode = "RGB", size = (width * 2, height * 2)) 37 | 38 | for x in range(0, 2 * width, 2): 39 | for y in range(0, 2 * height, 2): 40 | color1 = np.random.randint(255) 41 | color2 = np.random.randint(255) 42 | color3 = np.random.randint(255) 43 | new_secret_image.putpixel((x, y), (color1,color2,color3)) 44 | new_secret_image.putpixel((x+1,y), (255-color1,255-color2,255-color3)) 45 | new_secret_image.putpixel((x, y+1), (255-color1,255-color2,255-color3)) 46 | new_secret_image.putpixel((x+1,y+1), (color1,color2,color3)) 47 | 48 | return new_secret_image 49 | 50 | def generate_ciphered_image(secret_image, prepared_image): 51 | width, height = prepared_image.size 52 | ciphered_image = Image.new(mode = "RGB", size = (width * 2, height * 2)) 53 | for x in range(0, width*2, 2): 54 | for y in range(0, height*2, 2): 55 | sec = secret_image.getpixel((x,y)) 56 | msssg = prepared_image.getpixel((int(x/2),int(y/2))) 57 | color1 = (msssg[0]+sec[0])%256 58 | color2 = (msssg[1]+sec[1])%256 59 | color3 = (msssg[2]+sec[2])%256 60 | ciphered_image.putpixel((x, y), (color1,color2,color3)) 61 | ciphered_image.putpixel((x+1,y), (255-color1,255-color2,255-color3)) 62 | ciphered_image.putpixel((x, y+1), (255-color1,255-color2,255-color3)) 63 | ciphered_image.putpixel((x+1,y+1), (color1,color2,color3)) 64 | 65 | return ciphered_image 66 | 67 | 68 | def generate_image_back(secret_image, ciphered_image): 69 | width, height = secret_image.size 70 | new_image = Image.new(mode = "RGB", size = (int(width / 2), int(height / 2))) 71 | for x in range(0, width, 2): 72 | for y in range(0, height, 2): 73 | sec = secret_image.getpixel((x,y)) 74 | cip = ciphered_image.getpixel((x,y)) 75 | color1 = (cip[0]-sec[0])%256 76 | color2 = (cip[1]-sec[1])%256 77 | color3 = (cip[2]-sec[2])%256 78 | new_image.putpixel((int(x/2), int(y/2)), (color1,color2,color3)) 79 | 80 | return new_image 81 | 82 | 83 | #------------------------Encryption -------------------# 84 | def level_one_encrypt(Imagename): 85 | message_image = load_image(Imagename) 86 | size = message_image.size 87 | width, height = size 88 | 89 | secret_image = generate_secret(size) 90 | secret_image.save("secret.jpeg") 91 | 92 | prepared_image = prepare_message_image(message_image, size) 93 | ciphered_image = generate_ciphered_image(secret_image, prepared_image) 94 | ciphered_image.save("2-share_encrypt.jpeg") 95 | 96 | 97 | 98 | # -------------------- Construct Encrypted Image ----------------# 99 | def construct_enc_image(ciphertext,relength,width,height): 100 | asciicipher = binascii.hexlify(ciphertext) 101 | def replace_all(text, dic): 102 | for i, j in dic.iteritems(): 103 | text = text.replace(i, j) 104 | return text 105 | 106 | # use replace function to replace ascii cipher characters with numbers 107 | reps = {'a':'1', 'b':'2', 'c':'3', 'd':'4', 'e':'5', 'f':'6', 'g':'7', 'h':'8', 'i':'9', 'j':'10', 'k':'11', 'l':'12', 'm':'13', 'n':'14', 'o':'15', 'p':'16', 'q':'17', 'r':'18', 's':'19', 't':'20', 'u':'21', 'v':'22', 'w':'23', 'x':'24', 'y':'25', 'z':'26'} 108 | asciiciphertxt = replace_all(asciicipher, reps) 109 | 110 | # construct encrypted image 111 | step = 3 112 | encimageone=[asciiciphertxt[i:i+step] for i in range(0, len(asciiciphertxt), step)] 113 | # if the last pixel RGB value is less than 3-digits, add a digit a 1 114 | if int(encimageone[len(encimageone)-1]) < 100: 115 | encimageone[len(encimageone)-1] += "1" 116 | # check to see if we can divide the string into partitions of 3 digits. if not, fill in with some garbage RGB values 117 | if len(encimageone) % 3 != 0: 118 | while (len(encimageone) % 3 != 0): 119 | encimageone.append("101") 120 | 121 | encimagetwo=[(int(encimageone[int(i)]),int(encimageone[int(i+1)]),int(encimageone[int(i+2)])) for i in range(0, len(encimageone), step)] 122 | print(len(encimagetwo)) 123 | while (int(relength) != len(encimagetwo)): 124 | encimagetwo.pop() 125 | 126 | encim = Image.new("RGB", (int(width),int(height))) 127 | encim.putdata(encimagetwo) 128 | encim.save("visual_encrypt.jpeg") 129 | 130 | 131 | #------------------------- Visual-encryption -------------------------# 132 | def encrypt(imagename,password): 133 | plaintext = list() 134 | plaintextstr = "" 135 | 136 | im = Image.open(imagename) 137 | pix = im.load() 138 | 139 | width = im.size[0] 140 | height = im.size[1] 141 | 142 | # break up the image into a list, each with pixel values and then append to a string 143 | for y in range(0,height): 144 | for x in range(0,width): 145 | print (pix[x,y]) 146 | plaintext.append(pix[x,y]) 147 | print(width) 148 | print(height) 149 | 150 | # add 100 to each tuple value to make sure each are 3 digits long. 151 | for i in range(0,len(plaintext)): 152 | for j in range(0,3): 153 | aa = int(plaintext[i][j])+100 154 | plaintextstr = plaintextstr + str(aa) 155 | 156 | 157 | # length save for encrypted image reconstruction 158 | relength = len(plaintext) 159 | 160 | # append dimensions of image for reconstruction after decryption 161 | plaintextstr += "h" + str(height) + "h" + "w" + str(width) + "w" 162 | 163 | # make sure that plantextstr length is a multiple of 16 for AES. if not, append "n". 164 | while (len(plaintextstr) % 16 != 0): 165 | plaintextstr = plaintextstr + "n" 166 | 167 | # encrypt plaintext 168 | obj = AES.new(password, AES.MODE_CBC, 'This is an IV456') 169 | ciphertext = obj.encrypt(plaintextstr) 170 | 171 | # write ciphertext to file for analysis 172 | cipher_name = imagename + ".crypt" 173 | g = open(cipher_name, 'w') 174 | g.write(ciphertext) 175 | construct_enc_image(ciphertext,relength,width,height) 176 | print("Visual Encryption done.......") 177 | level_one_encrypt("visual_encrypt.jpeg") 178 | print("2-Share Encryption done.......") 179 | 180 | 181 | 182 | 183 | # ---------------------- decryption ---------------------- # 184 | def decrypt(ciphername,password): 185 | 186 | secret_image = Image.open("secret.jpeg") 187 | ima = Image.open("2-share_encrypt.jpeg") 188 | new_image = generate_image_back(secret_image, ima) 189 | new_image.save("2-share_decrypt.jpeg") 190 | print("2-share Decryption done....") 191 | cipher = open(ciphername,'r') 192 | ciphertext = cipher.read() 193 | 194 | # decrypt ciphertext with password 195 | obj2 = AES.new(password, AES.MODE_CBC, 'This is an IV456') 196 | decrypted = obj2.decrypt(ciphertext) 197 | 198 | # parse the decrypted text back into integer string 199 | decrypted = decrypted.replace("n","") 200 | 201 | # extract dimensions of images 202 | newwidth = decrypted.split("w")[1] 203 | newheight = decrypted.split("h")[1] 204 | 205 | # replace height and width with emptyspace in decrypted plaintext 206 | heightr = "h" + str(newheight) + "h" 207 | widthr = "w" + str(newwidth) + "w" 208 | decrypted = decrypted.replace(heightr,"") 209 | decrypted = decrypted.replace(widthr,"") 210 | 211 | # reconstruct the list of RGB tuples from the decrypted plaintext 212 | step = 3 213 | finaltextone=[decrypted[i:i+step] for i in range(0, len(decrypted), step)] 214 | finaltexttwo=[(int(finaltextone[int(i)])-100,int(finaltextone[int(i+1)])-100,int(finaltextone[int(i+2)])-100) for i in range(0, len(finaltextone), step)] 215 | 216 | # reconstruct image from list of pixel RGB tuples 217 | newim = Image.new("RGB", (int(newwidth), int(newheight))) 218 | newim.putdata(finaltexttwo) 219 | newim.save("visual_decrypt.jpeg") 220 | print("Visual Decryption done......") 221 | 222 | 223 | 224 | # --------------------- 225 | # GUI stuff starts here 226 | # --------------------- 227 | 228 | def pass_alert(): 229 | tkMessageBox.showinfo("Password Alert","Please enter a password.") 230 | 231 | def enc_success(imagename): 232 | tkMessageBox.showinfo("Success","Encrypted Image: " + imagename) 233 | 234 | # image encrypt button event 235 | def image_open(): 236 | global file_path_e 237 | 238 | enc_pass = passg.get() 239 | if enc_pass == "": 240 | pass_alert() 241 | else: 242 | password = hashlib.sha256(enc_pass).digest() 243 | filename = tkFileDialog.askopenfilename() 244 | file_path_e = os.path.dirname(filename) 245 | encrypt(filename,password) 246 | 247 | # image decrypt button event 248 | def cipher_open(): 249 | global file_path_d 250 | 251 | dec_pass = passg.get() 252 | if dec_pass == "": 253 | pass_alert() 254 | else: 255 | password = hashlib.sha256(dec_pass).digest() 256 | filename = tkFileDialog.askopenfilename() 257 | file_path_d = os.path.dirname(filename) 258 | decrypt(filename,password) 259 | 260 | class App: 261 | def __init__(self, master): 262 | global passg 263 | title = "Image Encryption" 264 | author = "Made by Aditya" 265 | msgtitle = Message(master, text =title) 266 | msgtitle.config(font=('helvetica', 17, 'bold'), width=200) 267 | msgauthor = Message(master, text=author) 268 | msgauthor.config(font=('helvetica',10), width=200) 269 | 270 | canvas_width = 200 271 | canvas_height = 50 272 | w = Canvas(master, 273 | width=canvas_width, 274 | height=canvas_height) 275 | msgtitle.pack() 276 | msgauthor.pack() 277 | w.pack() 278 | 279 | passlabel = Label(master, text="Enter Encrypt/Decrypt Password:") 280 | passlabel.pack() 281 | passg = Entry(master, show="*", width=20) 282 | passg.pack() 283 | 284 | self.encrypt = Button(master, 285 | text="Encrypt", fg="black", 286 | command=image_open, width=25,height=5) 287 | self.encrypt.pack(side=LEFT) 288 | self.decrypt = Button(master, 289 | text="Decrypt", fg="black", 290 | command=cipher_open, width=25,height=5) 291 | self.decrypt.pack(side=RIGHT) 292 | 293 | 294 | # ------------------ MAIN -------------# 295 | root = Tk() 296 | root.wm_title("Image Encryption") 297 | app = App(root) 298 | root.mainloop() 299 | --------------------------------------------------------------------------------