├── Extras
├── Picture1.png
├── cat.png
├── flower.png
├── garbled.gif
├── garbled.png
├── login.gif
├── mouse.png
├── obscure.gif
├── obscure.jpg
├── segmented.gif
└── segmented.png
├── LICENSE
├── README.md
├── assets
├── back.jpg
└── mic.jpg
├── credentialImages
├── cat1.png
├── cat2.png
├── cat3.png
├── flower1.png
├── flower2.png
├── flower3.png
├── mouse1.png
├── mouse2.png
├── mouse3.png
└── orig_credentials.txt
├── custom_button.py
├── garbled.py
├── garbledImages
├── garbled1.png
├── garbled2.png
├── garbled3.png
├── garbled4.png
├── garbled5.png
└── original_garbled.txt
├── main_menu.py
├── obscure.py
├── obscuredImages
├── obscure1.jpg
├── obscure2.jpg
├── obscure3.jpg
├── obscure4.jpg
├── obscure5.jpg
└── original_obscure.txt
├── password.py
├── segmentedImages
├── circle
│ ├── circle1.jpg
│ ├── circle2.jpg
│ ├── circle3.jpg
│ └── circle4.jpg
└── order.jpg
├── segments.py
└── utils.py
/Extras/Picture1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/Picture1.png
--------------------------------------------------------------------------------
/Extras/cat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/cat.png
--------------------------------------------------------------------------------
/Extras/flower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/flower.png
--------------------------------------------------------------------------------
/Extras/garbled.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/garbled.gif
--------------------------------------------------------------------------------
/Extras/garbled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/garbled.png
--------------------------------------------------------------------------------
/Extras/login.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/login.gif
--------------------------------------------------------------------------------
/Extras/mouse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/mouse.png
--------------------------------------------------------------------------------
/Extras/obscure.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/obscure.gif
--------------------------------------------------------------------------------
/Extras/obscure.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/obscure.jpg
--------------------------------------------------------------------------------
/Extras/segmented.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/segmented.gif
--------------------------------------------------------------------------------
/Extras/segmented.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/Extras/segmented.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Hassan Shahzad
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Graphical Password Authentication System
2 |
3 |
4 |
5 |
6 |
7 | ## Description:
8 | For this project, we designed a Graphical Password Authentication System. This is used to increase the protection/security of a website. Our system is divided into further 4 layers of protection. Each layer is totally different and diverse than the others. This not only increases protection, but also makes sure that no non-human can log in to your account using different activities such as Brute Force Algorithm and so on. The motivation for this project came from a recent attack named **Pegasus** in which people had their mobile phones compromised for almost a decade without them ever getting the slightest clue. This motivated us to build a stronger authentication system that generates randomized methods which could weaken the attack and eventually prevent it. The 4 layers of Protection that we are using are as follows:
9 | 1. Segmented Images Authentication
10 | 2. Password Image Authentication
11 | 3. Obscured Images Authentication
12 | 4. Garbled Images Authentication
13 |
14 | The above layers have been sorted according to their complexities (1 being the least complex and 4 being most complex). The detailed explanation of the layers are as follows:
15 |
16 |
17 | ### 1: Segmented Images Authentication:
18 | For this layer, the user will be showed 4 different images. These images will be a division of a whole image. User will have to select the correct order of the images. The logic can be explained better with the following picture:
19 |
20 |
21 |
22 | As can be seen in the above image, a circle is divided into 4 parts. These 4 parts will be randomly displayed on the screen and user will be asked to select the pieces in correct order. The order is determined on the basis of the time of click. If an image is clicked first, it will be selected as the first image and so on. If a user selects all 4 pieces in the correct order, he/she will be authenticated.
23 |
24 | The key thing to note here is how it offers security but without compromising usability – it is very easy for even young humans to recognise patterns in images and choose the correct order.
25 |
26 | According to our implementation, we first display the pieces of circle in a randomized order every time. The user is then asked to select the images in the correct order as being displayed on the screen. Our code will detect the time of click here. Every click on a picture is stored along with the time it was clicked. Once all images are clicked, we simply sort by time and check that they were selected in the correct order. If yes, then the user will be authenticated.
27 |
28 | This layer in our system can be seen as follows:
29 |
30 |
31 |
32 |
33 |
34 | ### 2: Password Image Authentication:
35 | For this layer, we took inspiration from Meezan Bank’s authentication system. Whenever a user registers, he/she is asked to select an image category from the 3 given categories:
36 | - Cat
37 | - Mouse
38 | - Flower
39 |
40 | Whatever the user selects, is associated with his/her password and every time the user logs in, he/she will be asked to select the same image from the randomly displayed images.
41 |
42 | Now here’s the twist. We have stored multiple images for each category. So, if a user selects cat, he/she will not be displayed the same cat every single time. The images per category are different as can be seen below.
43 | #### a) Cat:
44 |
45 |
46 |
47 |
48 | #### b) Mouse:
49 |
50 |
51 |
52 |
53 | #### c) Flower:
54 |
55 |
56 |
57 |
58 | According to our implementation, we have stored 3 categories i.e., cat, mouse, flower in our database. Whatever the user has selected while registering has been stored into the database along with his password. Each category has 3 different versions named 0, 1, 2. At the start of the program, a random number is generated between 0 and 2. Whatever the number is, is the picture of each category that is to be displayed. This is to just add a bit more complexity to the code. Let’s say a user has selected image 1 of cat. Upon authentication he may be shown image 0 of cat (which will be a different cat) but the key thing is that it will be a cat and the user must select it in order to be authenticated.
59 |
60 | This layer in our system can be seen as follows:
61 |
62 |
63 |
64 |
65 | ### 3: Obscure Image Authentication:
66 | This is one of the most interesting layers. In this layer, not only are we preventing bots but we are also enhancing security by introducing image-to-speech-to-text concept. Let’s dig deeper into what this concept really is.
67 |
68 | #### Image-to-Speech-to-Text:
69 | In this concept, a user is displayed an image with obscure text. The reason for adding this obscurity is to confuse a NLP or OCR type mechanisms in bypassing the authentication. Random words are generated on a file which is then covered with an obscure text.
70 |
71 | For example:
72 |
73 |
74 |
75 |
76 | This picture is then displayed to the user and user is asked to speak the words in the given image. Now, here a trained model will give false results as it wouldn’t know which text to read whereas a human can do so.
77 |
78 | Then the user will speak the text in correct order which our system will then convert to text and verify if the user spoke correct text. If verified, the user will be granted access.
79 |
80 | For this feature, we are using **“Speech Recognition”** module of Python. User will be displayed the obscure text image and there will be a microphone button. When user will click the button, the recording will start and user will be asked to say the words in the image. When user says all the words, he/she must say **stop** in order for the program to stop recording. Then all the speech will be converted into individual words and stored in each index of an array. This array will then be compared to the expected output array. If both the arrays match, then the user will be authenticated.
81 |
82 | This module can be installed using: ***pip install speechrecognition***
83 |
84 | This layer in our system can be seen as follows:
85 |
86 |
87 |
88 |
89 | ### 4: Garbled Image Authentication:
90 | The last and the most difficult layer is the garbled text authentication. In this layer, the user will be displayed a Garbled text whose readability will be really low and user will be asked to read and then type in the text. The garbled texts will be randomly generated as follows:
91 |
92 |
93 |
94 | For this layer, we have generated multiple garbled text images and stored the correct value of each image in a file. User is shown a random image in the start of this layer and is asked to type in the correct text. Whatever the user types is then compared to the already stored correct values and if the answer is correct, then user will be authenticated and authentication dialogue box will pop up.
95 |
96 | This layer in our system can be seen as follows:
97 |
98 |
99 |
100 |
101 | ## Security Analysis:
102 | Following is the detailed security analysis of our system:
103 |
104 | ### 1: Issues Covered:
105 | The majority of applications/websites use text-based passwords to authenticate a user, with the additional use of CAPTCHA to verify that the user is a human. Unfortunately, this is not very secure and leaves the system vulnerable to different sorts of attacks. While text-based passwords sound secure in theory, in practice most users will end up making simple, common passwords that are frequently repeated across different applications or accounts. Bot attacks or hackers can take advantage of this and launch dictionary attacks, try to brute force the password or employ other ways to compromise user accounts.
106 |
107 | ### 2: Security Strengths:
108 | Graphical passwords are a more secure alternative to standard text-based passwords, especially as they don’t significantly lower usability. Using graphical password authentication, we can avoid the problem of keystroke logging, and be protected against dictionary attacks and social engineering. This technique for user authentication also requires human interaction on part of the user, which doubles as verifying the user was a human without having to make use of CAPTCHA (which is infamously annoying for users.) There will be several security layers, and the system will be customizable i.e., you can choose the types of security you want, depending on your security requirements.
109 |
110 | ### 3: Security Weaknesses:
111 | There are no major security vulnerabilities. However, our system is limited in scope so there are very small number of options for each module. Such as garbled text has a limited number of pictures to be chosen randomly from. This is not an inherent weakness of the system, as on a larger scale it could be adapted to generate or segment images dynamically and so on. But in the current state of the system, it would be possible for a computer to eventually brute force its way to the solution.
112 |
113 | ## Contributors:
114 | In the end, I'd like to mention my group members who helped me alot in this project. You can find them at:
115 |
116 | [Sana Khan](https://github.com/sanaa-khan)
117 |
118 | [Wajeeha Malik](https://github.com/wajeehamalik913)
119 |
120 | ## 📫 Contact Me:
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/assets/back.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/assets/back.jpg
--------------------------------------------------------------------------------
/assets/mic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/assets/mic.jpg
--------------------------------------------------------------------------------
/credentialImages/cat1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/cat1.png
--------------------------------------------------------------------------------
/credentialImages/cat2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/cat2.png
--------------------------------------------------------------------------------
/credentialImages/cat3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/cat3.png
--------------------------------------------------------------------------------
/credentialImages/flower1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/flower1.png
--------------------------------------------------------------------------------
/credentialImages/flower2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/flower2.png
--------------------------------------------------------------------------------
/credentialImages/flower3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/flower3.png
--------------------------------------------------------------------------------
/credentialImages/mouse1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/mouse1.png
--------------------------------------------------------------------------------
/credentialImages/mouse2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/mouse2.png
--------------------------------------------------------------------------------
/credentialImages/mouse3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/credentialImages/mouse3.png
--------------------------------------------------------------------------------
/credentialImages/orig_credentials.txt:
--------------------------------------------------------------------------------
1 | wajeeha a09b0c9c4bf4bd4c9c5ec45f574531c7d0c8580825d6d8586954eddfbfefb250 cat
2 | sana 2f6ed41b80d58a97523dfe13825c9f4c730e51d4fe149727fc8ab3466cf8a84f dog
3 | hassan 95dcd54df7b0b711868e406c56d0ab9ba99244cbd1b31c5fecc5a6054c0f26a9 mouse
--------------------------------------------------------------------------------
/custom_button.py:
--------------------------------------------------------------------------------
1 | import tkinter
2 | import sys
3 |
4 |
5 | class TkinterCustomButton(tkinter.Frame):
6 | """ tkinter custom button with border, rounded corners and hover effect
7 | Arguments: master= where to place button
8 | bg_color= background color, None is standard,
9 | fg_color= foreground color, blue is standard,
10 | hover_color= foreground color, lightblue is standard,
11 | border_color= foreground color, None is standard,
12 | border_width= border thickness, 0 is standard,
13 | command= callback function, None is standard,
14 | width= width of button, 110 is standard,
15 | height= width of button, 35 is standard,
16 | corner_radius= corner radius, 10 is standard,
17 | text_font= (, ),
18 | text_color= text color, white is standard,
19 | text= text of button,
20 | hover= hover effect, True is standard,
21 | image= PIL.PhotoImage, standard is None"""
22 |
23 | def __init__(self,
24 | bg_color=None,
25 | fg_color="#2874A6",
26 | hover_color="#5499C7",
27 | border_color=None,
28 | border_width=0,
29 | command=None,
30 | width=120,
31 | height=40,
32 | corner_radius=10,
33 | text_font=None,
34 | text_color="white",
35 | text="CustomButton",
36 | hover=True,
37 | image=None,
38 | *args, **kwargs):
39 | super().__init__(*args, **kwargs)
40 |
41 | if bg_color is None:
42 | self.bg_color = self.master.cget("bg")
43 | else:
44 | self.bg_color = bg_color
45 |
46 | self.fg_color = fg_color
47 | self.hover_color = hover_color
48 | self.border_color = border_color
49 |
50 | self.width = width
51 | self.height = height
52 |
53 | if corner_radius*2 > self.height:
54 | self.corner_radius = self.height/2
55 | elif corner_radius*2 > self.width:
56 | self.corner_radius = self.width/2
57 | else:
58 | self.corner_radius = corner_radius
59 |
60 | self.border_width = border_width
61 |
62 | if self.corner_radius >= self.border_width:
63 | self.inner_corner_radius = self.corner_radius - self.border_width
64 | else:
65 | self.inner_corner_radius = 0
66 |
67 | self.text = text
68 | self.text_color = text_color
69 | if text_font is None:
70 | if sys.platform == "darwin": # macOS
71 | self.text_font = ("Avenir", 13)
72 | elif "win" in sys.platform: # Windows
73 | self.text_font = ("Century Gothic", 11)
74 | else:
75 | self.text_font = ("TkDefaultFont")
76 | else:
77 | self.text_font = text_font
78 |
79 | self.image = image
80 |
81 | self.function = command
82 | self.hover = hover
83 |
84 | self.configure(width=self.width, height=self.height)
85 |
86 | if sys.platform == "darwin" and self.function is not None:
87 | self.configure(cursor="pointinghand")
88 |
89 | self.canvas = tkinter.Canvas(master=self,
90 | highlightthicknes=0,
91 | background=self.bg_color,
92 | width=self.width,
93 | height=self.height)
94 | self.canvas.place(x=0, y=0)
95 |
96 | if self.hover is True:
97 | self.canvas.bind("", self.on_enter)
98 | self.canvas.bind("", self.on_leave)
99 |
100 | self.canvas.bind("", self.clicked)
101 | self.canvas.bind("", self.clicked)
102 |
103 | self.canvas_fg_parts = []
104 | self.canvas_border_parts = []
105 | self.text_part = None
106 | self.text_label = None
107 | self.image_label = None
108 |
109 | self.draw()
110 |
111 | def draw(self):
112 | self.canvas.delete("all")
113 | self.canvas_fg_parts = []
114 | self.canvas_border_parts = []
115 | self.canvas.configure(bg=self.bg_color)
116 |
117 | # border button parts
118 | if self.border_width > 0:
119 |
120 | if self.corner_radius > 0:
121 | self.canvas_border_parts.append(self.canvas.create_oval(0,
122 | 0,
123 | self.corner_radius * 2,
124 | self.corner_radius * 2))
125 | self.canvas_border_parts.append(self.canvas.create_oval(self.width - self.corner_radius * 2,
126 | 0,
127 | self.width,
128 | self.corner_radius * 2))
129 | self.canvas_border_parts.append(self.canvas.create_oval(0,
130 | self.height - self.corner_radius * 2,
131 | self.corner_radius * 2,
132 | self.height))
133 | self.canvas_border_parts.append(self.canvas.create_oval(self.width - self.corner_radius * 2,
134 | self.height - self.corner_radius * 2,
135 | self.width,
136 | self.height))
137 |
138 | self.canvas_border_parts.append(self.canvas.create_rectangle(0,
139 | self.corner_radius,
140 | self.width,
141 | self.height - self.corner_radius))
142 | self.canvas_border_parts.append(self.canvas.create_rectangle(self.corner_radius,
143 | 0,
144 | self.width - self.corner_radius,
145 | self.height))
146 |
147 | # inner button parts
148 |
149 | if self.corner_radius > 0:
150 | self.canvas_fg_parts.append(self.canvas.create_oval(self.border_width,
151 | self.border_width,
152 | self.border_width + self.inner_corner_radius * 2,
153 | self.border_width + self.inner_corner_radius * 2))
154 | self.canvas_fg_parts.append(self.canvas.create_oval(self.width - self.border_width - self.inner_corner_radius * 2,
155 | self.border_width,
156 | self.width - self.border_width,
157 | self.border_width + self.inner_corner_radius * 2))
158 | self.canvas_fg_parts.append(self.canvas.create_oval(self.border_width,
159 | self.height - self.border_width - self.inner_corner_radius * 2,
160 | self.border_width + self.inner_corner_radius * 2,
161 | self.height-self.border_width))
162 | self.canvas_fg_parts.append(self.canvas.create_oval(self.width - self.border_width - self.inner_corner_radius * 2,
163 | self.height - self.border_width - self.inner_corner_radius * 2,
164 | self.width - self.border_width,
165 | self.height - self.border_width))
166 |
167 | self.canvas_fg_parts.append(self.canvas.create_rectangle(self.border_width + self.inner_corner_radius,
168 | self.border_width,
169 | self.width - self.border_width - self.inner_corner_radius,
170 | self.height - self.border_width))
171 | self.canvas_fg_parts.append(self.canvas.create_rectangle(self.border_width,
172 | self.border_width + self.inner_corner_radius,
173 | self.width - self.border_width,
174 | self.height - self.inner_corner_radius - self.border_width))
175 |
176 | for part in self.canvas_fg_parts:
177 | self.canvas.itemconfig(part, fill=self.fg_color, width=0)
178 |
179 | for part in self.canvas_border_parts:
180 | self.canvas.itemconfig(part, fill=self.border_color, width=0)
181 |
182 | # no image given
183 | if self.image is None:
184 | # create tkinter.Label with text
185 | self.text_label = tkinter.Label(master=self,
186 | text=self.text,
187 | font=self.text_font,
188 | bg=self.fg_color,
189 | fg=self.text_color)
190 | self.text_label.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)
191 |
192 | # bind events the the button click and hover events also to the text_label
193 | if self.hover is True:
194 | self.text_label.bind("", self.on_enter)
195 | self.text_label.bind("", self.on_leave)
196 |
197 | self.text_label.bind("", self.clicked)
198 | self.text_label.bind("", self.clicked)
199 |
200 | self.set_text(self.text)
201 |
202 | # use the given image
203 | else:
204 | # create tkinter.Label with image on it
205 | self.image_label = tkinter.Label(master=self,
206 | image=self.image,
207 | bg=self.fg_color)
208 |
209 | self.image_label.place(relx=0.5,
210 | rely=0.5,
211 | anchor=tkinter.CENTER)
212 |
213 | # bind events the the button click and hover events also to the image_label
214 | if self.hover is True:
215 | self.image_label.bind("", self.on_enter)
216 | self.image_label.bind("", self.on_leave)
217 |
218 | self.image_label.bind("", self.clicked)
219 | self.image_label.bind("", self.clicked)
220 |
221 | def configure_color(self, bg_color=None, fg_color=None, hover_color=None, text_color=None):
222 | if bg_color is not None:
223 | self.bg_color = bg_color
224 | else:
225 | self.bg_color = self.master.cget("bg")
226 |
227 | if fg_color is not None:
228 | self.fg_color = fg_color
229 |
230 | # change background color of image_label
231 | if self.image is not None:
232 | self.image_label.configure(bg=self.fg_color)
233 |
234 | if hover_color is not None:
235 | self.hover_color = hover_color
236 |
237 | if text_color is not None:
238 | self.text_color = text_color
239 | if self.text_part is not None:
240 | self.canvas.itemconfig(self.text_part, fill=self.text_color)
241 |
242 | self.draw()
243 |
244 | def set_text(self, text):
245 | if self.text_label is not None:
246 | self.text_label.configure(text=text)
247 |
248 | def on_enter(self, event=0):
249 | for part in self.canvas_fg_parts:
250 | self.canvas.itemconfig(part, fill=self.hover_color, width=0)
251 |
252 | if self.text_label is not None:
253 | # change background color of image_label
254 | self.text_label.configure(bg=self.hover_color)
255 |
256 | if self.image_label is not None:
257 | # change background color of image_label
258 | self.image_label.configure(bg=self.hover_color)
259 |
260 | def on_leave(self, event=0):
261 | for part in self.canvas_fg_parts:
262 | self.canvas.itemconfig(part, fill=self.fg_color, width=0)
263 |
264 | if self.text_label is not None:
265 | # change background color of image_label
266 | self.text_label.configure(bg=self.fg_color)
267 |
268 | if self.image_label is not None:
269 | # change background color of image_label
270 | self.image_label.configure(bg=self.fg_color)
271 |
272 | def clicked(self, event=0):
273 | if self.function is not None:
274 | self.function()
275 | self.on_leave()
--------------------------------------------------------------------------------
/garbled.py:
--------------------------------------------------------------------------------
1 | import tkinter
2 | from tkinter import *
3 | import custom_button
4 | import main_menu
5 |
6 | import utils
7 | from PIL import ImageTk, Image
8 | from tkinter import Entry
9 | import random
10 |
11 |
12 | def load_menu(window, frame):
13 | frame.pack_forget()
14 | main_menu.start(window)
15 |
16 |
17 | def start(window):
18 | filepath = "garbledImages/original_garbled.txt" # File Path
19 | garbledImages = utils.getGarbledImages()
20 | num = random.randint(0, len(garbledImages) - 1)
21 | filename = garbledImages[num]
22 |
23 | f = open(filepath, "r")
24 |
25 | while True:
26 | string = f.readline() # Reading file line by line
27 | s1 = string.split(' ')[0] # Getting first word (filename) of line
28 | if s1 == filename[0:len(filename) - 4]: # Don't need the file extension, only name
29 | break
30 | # print("Original = ", string)
31 | string = string[9:] # Cropping string
32 | string = string.replace(' ', '-') # Replacing spaces with dashes
33 | original_text = string
34 | original_text = original_text.rstrip() # Removing \n
35 | f.close()
36 |
37 | print(original_text)
38 | print(filename)
39 |
40 | window.title("Graphical Authentication System")
41 | window.geometry("1280x600")
42 |
43 | garbled_frame = Frame(window, height=600, width=1280)
44 | garbled_frame.pack(fill='both', expand=1)
45 |
46 | label = Label(garbled_frame, text="Type the words in the image", font=('Calibri', 20))
47 | label.pack(padx=40, pady=10)
48 |
49 | canvas = Canvas(garbled_frame, width=450, height=300)
50 | img = (Image.open("garbledImages/" + filename))
51 | img = img.resize((450, 300), Image.ANTIALIAS)
52 | img = ImageTk.PhotoImage(img)
53 | canvas.create_image(10, 10, anchor=NW, image=img)
54 | canvas.place(relx=0.45, rely=0.5, anchor=E)
55 |
56 | def check():
57 | entered_text = input.get()
58 | if entered_text == original_text:
59 | print("Authenticated")
60 | utils.create_popup(msg="Authenticated :)", font="Gabriola 28 bold")
61 | else:
62 | print("Authentication Failed")
63 | utils.create_popup(msg="Go Away Robot >_<", font="Gabriola 28 bold")
64 |
65 | input = StringVar()
66 | Label(garbled_frame, text="Enter word", font="ariel 16 bold").place(relx=0.7, rely=0.40, anchor=CENTER)
67 | Entry(garbled_frame, textvariable=input, font="ariel 12 bold", relief="groove", width=30, justify=CENTER).place(
68 | relx=0.7,
69 | rely=0.5,
70 | anchor=CENTER)
71 |
72 | custom_button.TkinterCustomButton(master=garbled_frame, text="Check", height=40, corner_radius=10,
73 | command=check).place(relx=0.7, rely=0.6, anchor=CENTER)
74 |
75 | custom_button.TkinterCustomButton(master=garbled_frame, text="Go Back", height=40, corner_radius=10,
76 | command=lambda: load_menu(window, garbled_frame)).place(relx=0.08, rely=0.08, anchor=CENTER)
77 |
78 | while True:
79 | window.update_idletasks()
80 | window.update()
81 |
--------------------------------------------------------------------------------
/garbledImages/garbled1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/garbledImages/garbled1.png
--------------------------------------------------------------------------------
/garbledImages/garbled2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/garbledImages/garbled2.png
--------------------------------------------------------------------------------
/garbledImages/garbled3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/garbledImages/garbled3.png
--------------------------------------------------------------------------------
/garbledImages/garbled4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/garbledImages/garbled4.png
--------------------------------------------------------------------------------
/garbledImages/garbled5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/garbledImages/garbled5.png
--------------------------------------------------------------------------------
/garbledImages/original_garbled.txt:
--------------------------------------------------------------------------------
1 | garbled1 future
2 | garbled2 accent
3 | garbled3 risk
4 | garbled4 rumor
5 | garbled5 serious
--------------------------------------------------------------------------------
/main_menu.py:
--------------------------------------------------------------------------------
1 | # Import the required libraries
2 | from tkinter import *
3 | from tkinter import font
4 | import custom_button
5 | import garbled
6 | import obscure
7 | import password
8 | import segments
9 |
10 |
11 | def load_garbled(window, menu_frame):
12 | menu_frame.pack_forget()
13 | garbled.start(window)
14 |
15 |
16 | def load_obscured(window, menu_frame):
17 | menu_frame.pack_forget()
18 | obscure.start(window)
19 |
20 |
21 | def load_segmented(window, menu_frame):
22 | menu_frame.pack_forget()
23 | segments.start(window)
24 |
25 |
26 | def load_password(window, menu_frame):
27 | menu_frame.pack_forget()
28 | password.start(window)
29 |
30 |
31 | def start(win):
32 | win.geometry("1280x600")
33 | win.title("Graphical Authentication System")
34 |
35 | menu_frame = Frame(win, height=600, width=1280)
36 | menu_frame.pack(fill='both', expand=1)
37 |
38 | label = Label(menu_frame, text="Graphical Authentication System", font=('Freestyle Script', 54))
39 | label.pack(padx=40, pady=30)
40 |
41 | btn_height = 90
42 | btn_width = 450
43 | btn_font = ('Trebuchet MS', 14)
44 |
45 | btn1 = custom_button.TkinterCustomButton(master=menu_frame, text="Test Garbled Images", text_font=btn_font,
46 | height=btn_height, width=btn_width, corner_radius=10,
47 | command=lambda: load_garbled(win, menu_frame)).place(relx=0.3, rely=0.4,
48 | anchor=CENTER)
49 | btn2 = custom_button.TkinterCustomButton(master=menu_frame, text="Test Segmented Images", text_font=btn_font,
50 | height=btn_height, width=btn_width, corner_radius=10,
51 | command=lambda: load_segmented(win, menu_frame)).place(relx=0.3,
52 | rely=0.7,
53 | anchor=CENTER)
54 | btn3 = custom_button.TkinterCustomButton(master=menu_frame, text="Test Obscured Images", text_font=btn_font,
55 | height=btn_height, width=btn_width, corner_radius=10,
56 | command=lambda: load_obscured(win, menu_frame)).place(relx=0.7,
57 | rely=0.4,
58 | anchor=CENTER)
59 | btn4 = custom_button.TkinterCustomButton(master=menu_frame, text="Test Password/Image Authentication",
60 | text_font=btn_font,
61 | height=btn_height, width=btn_width, corner_radius=10,
62 | command=lambda: load_password(win, menu_frame)).place(relx=0.7,
63 | rely=0.7,
64 | anchor=CENTER)
65 |
66 | win.mainloop()
67 |
68 |
69 | if __name__ == "__main__":
70 | win = Tk()
71 | start(win)
72 |
--------------------------------------------------------------------------------
/obscure.py:
--------------------------------------------------------------------------------
1 | import tkinter
2 | from tkinter import *
3 | import custom_button
4 | import main_menu
5 | import speech_recognition as sr
6 |
7 | import utils
8 | from PIL import ImageTk, Image
9 | import random
10 |
11 |
12 | def load_menu(window, frame):
13 | frame.pack_forget()
14 | main_menu.start(window)
15 |
16 |
17 | original_text = []
18 |
19 |
20 | def toggle(event):
21 | input_text = None
22 |
23 | while True:
24 | e = sr.Recognizer() # Recognizes all input devices
25 | with sr.Microphone() as source: # setting microphone as default input device
26 | try:
27 | print("Say Something. Say 'stop' inorder to stop")
28 | audio = e.listen(source) # Listens audio
29 | input_text = e.recognize_google(audio) # Recognizes text using speech recognition
30 | if input_text == "stop": # Break condition
31 | break
32 | except:
33 | print("Exception occured when trying to record")
34 | break
35 | input_text = input_text[:-5] # Removing stop from the end of line
36 | input_text = input_text.rstrip() # Removing \n
37 | input_text = input_text.lower() # Converting everything to lowercase
38 | input_text = input_text.replace(' ', '-') # Replacing spaces with dashes
39 |
40 | print("Original Text = ", original_text[0])
41 | print("Input Text = ", input_text)
42 |
43 | if original_text[0] == input_text:
44 | print("Authenticated")
45 | utils.create_popup(msg="Authenticated :)", font="Gabriola 28 bold")
46 | else:
47 | print("Authentication Failed")
48 | utils.create_popup(msg="Go Away Robot >_<", font="Gabriola 28 bold")
49 |
50 |
51 | def start(window):
52 | obscuredImages = utils.getObscuredImages()
53 | num = random.randint(1, len(obscuredImages) - 1)
54 | filename = obscuredImages[num] # Filename that will be displayed
55 | filepath = "obscuredImages/original_obscure.txt" # File Path
56 |
57 | f = open(filepath, "r")
58 |
59 | while True:
60 | string = f.readline() # Reading file line by line
61 | s1 = string.split(' ')[0] # Getting first word (filename) of line
62 | if s1 == filename[0:len(filename) - 4]: # Don't need the file extension, only name
63 | break
64 | # print("Original = ", string)
65 | string = string[9:] # Cropping string
66 | string = string.replace(' ', '-') # Replacing spaces with dashes
67 | string = string
68 | original_text.append(string.rstrip()) # Removing \n
69 | f.close()
70 |
71 | obscure_frame = Frame(window, height=600, width=1280)
72 | obscure_frame.pack(fill='both', expand=1)
73 |
74 | window.title("Graphical Authentication System")
75 | window.geometry("1280x600")
76 |
77 | label = Label(obscure_frame, text="Click on the microphone and speak the words in the following image",
78 | font=('Calibri', 20))
79 | label.pack(padx=40, pady=10)
80 |
81 | canvas = Canvas(obscure_frame, width=450, height=300)
82 | img = (Image.open("obscuredImages/" + filename))
83 | img = img.resize((450, 300), Image.ANTIALIAS)
84 | img = ImageTk.PhotoImage(img)
85 | canvas.create_image(10, 10, anchor=NW, image=img)
86 | canvas.pack(padx=10, pady=10)
87 |
88 | canvas2 = Canvas(obscure_frame, width=200, height=170)
89 | canvas2.bind("", toggle)
90 | img2 = (Image.open("assets/mic.jpg"))
91 | img2 = img2.resize((200, 170), Image.ANTIALIAS)
92 | img2 = ImageTk.PhotoImage(img2)
93 | canvas2.create_image(10, 10, anchor=NW, image=img2)
94 | canvas2.pack(padx=20, pady=20)
95 |
96 | custom_button.TkinterCustomButton(master=obscure_frame, text="Go Back", height=40, corner_radius=10,
97 | command=lambda: load_menu(window, obscure_frame)).place(relx=0.08, rely=0.08,
98 | anchor=CENTER)
99 |
100 | while True:
101 | window.update_idletasks()
102 | window.update()
103 |
--------------------------------------------------------------------------------
/obscuredImages/obscure1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/obscuredImages/obscure1.jpg
--------------------------------------------------------------------------------
/obscuredImages/obscure2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/obscuredImages/obscure2.jpg
--------------------------------------------------------------------------------
/obscuredImages/obscure3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/obscuredImages/obscure3.jpg
--------------------------------------------------------------------------------
/obscuredImages/obscure4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/obscuredImages/obscure4.jpg
--------------------------------------------------------------------------------
/obscuredImages/obscure5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/obscuredImages/obscure5.jpg
--------------------------------------------------------------------------------
/obscuredImages/original_obscure.txt:
--------------------------------------------------------------------------------
1 | obscure1 hello cook cash money dignity
2 | obscure2 exposure picture robot disappear
3 | obscure3 timber eavesdrop dress note
4 | obscure4 pain combination professional
5 | obscure5 waist support confine forest
--------------------------------------------------------------------------------
/password.py:
--------------------------------------------------------------------------------
1 | from tkinter import messagebox
2 | import copy
3 | import hashlib
4 | from random import randint
5 |
6 | import tkinter
7 | from tkinter import *
8 | import custom_button
9 | import main_menu
10 |
11 | import utils
12 | from PIL import ImageTk, Image
13 | from tkinter import Entry
14 |
15 | s_image = []
16 | s_image.append("")
17 |
18 | def load_menu(window, frame):
19 | frame.pack_forget()
20 | main_menu.start(window)
21 |
22 |
23 | # saves image selected by user
24 | def clicked(canvas, img_name, event):
25 | canvas.config(highlightthickness=1, highlightbackground="black")
26 | s_image[0] = img_name;
27 | # print(s_image[0])
28 |
29 |
30 | # authenticate credentials provided by users
31 | def authenticate(selected_image, selected_password, selected_name):
32 | # checks if there is no empty entry
33 | if selected_name == "":
34 | messagebox.showinfo("Login System", "Please enter the Username")
35 | elif selected_password == "":
36 | messagebox.showinfo("Login System", "Please enter the Password")
37 | elif selected_name == "" and selected_password == "":
38 | messagebox.showinfo("Login System", "Please enter the Username and Password")
39 | # print("hiii",selected_image)
40 |
41 | # taking hash of password entered as its hash stored in backend
42 | h = hashlib.new('sha512_256')
43 | h.update(selected_password.encode())
44 | selected_password = h.hexdigest()
45 | filepath = "credentialImages/orig_credentials.txt" # File Path
46 | f = open(filepath, "r")
47 | name = ""
48 | password = ""
49 | image = ""
50 | str = ""
51 | isUser = 0
52 | # file reading to get original credentials
53 | while True:
54 | string = f.readline() # Reading file line by line
55 | if string == "":
56 | if (isUser == 0):
57 | print("username not exist")
58 | messagebox.showinfo("Login System", "password is not correct")
59 | break
60 | info = string.split(" ")
61 | name = copy.deepcopy(info[0])
62 | password = copy.deepcopy(info[1])
63 | image = copy.deepcopy(info[2])
64 | name = name.rstrip()
65 | password = password.rstrip()
66 | image = image.rstrip()
67 |
68 | # checks the credentials by somparing with original one
69 | if name == selected_name:
70 | isUser = 1
71 | if password == selected_password:
72 | if image == selected_image:
73 | print("authenticated!!")
74 | messagebox.showinfo("Login System", "authenticated!!")
75 | break
76 | else:
77 | print("image is not correct")
78 | messagebox.showinfo("Login System", "image is not correct")
79 |
80 | break
81 | else:
82 | print("password is not correct")
83 | messagebox.showinfo("Login System", "password is not correct")
84 | break
85 |
86 |
87 | # login page canvas
88 | def create_canvas(window):
89 | window.title("Login Page")
90 | window.geometry("1280x600")
91 |
92 | root = Frame(window, height=600, width=1280)
93 | root.pack(fill='both', expand=1)
94 |
95 | #root.title("Login Page")
96 | #root.resizable(0, 0)
97 | width = 700
98 | height = 700
99 | # image class names
100 | img_name1 = "cat"
101 | img_name2 = "flower"
102 | img_name3 = "mouse"
103 |
104 | # Generates random number to display images
105 | num = randint(0, 2)
106 | print("Random number = ", num)
107 | selected_image = ""
108 |
109 | # getting image paths from utils
110 | imgList = utils.getCredentialImages()
111 |
112 | # canvas for title
113 | canvas = Canvas(root, width=width, height=height, bd=0, highlightthickness=0)
114 | canvas.pack(fill=BOTH, expand=True)
115 | canvas.create_image(0, 0, anchor='nw')
116 | label = Label(root, text="Login Page", font=("Ariel 15 bold"))
117 | canvas.create_window(550, 40, anchor="nw", window=label)
118 |
119 | # canvas for username title
120 | user_label = Label(root, text="User name:", font=("Ariel 12 bold"))
121 | canvas.create_window(480, 130, anchor="nw", window=user_label)
122 |
123 | # canvas for password title
124 | password_label = Label(root, text="Password:", font=("Ariel 12 bold"))
125 | canvas.create_window(480, 210, anchor="nw", window=password_label)
126 |
127 | # usernmae input feild display
128 | user_entry = Entry(root, font=("Ariel 12"))
129 | user_entry.focus()
130 | selected_name = user_entry.get()
131 | canvas.create_window(580, 130, anchor="nw", window=user_entry)
132 |
133 | # password input feild display
134 | pas = StringVar()
135 | password_entry = Entry(root, textvar=pas, font=("Ariel 12"), show="*")
136 | selected_password = password_entry.get()
137 | canvas.create_window(580, 210, anchor="nw", window=password_entry)
138 |
139 | # Random image display from first class
140 | canvas2 = Canvas(root, width=110, height=70)
141 | canvas2.bind("",
142 | lambda event: clicked(canvas2, img_name1, event)) # binding button to check if image is clicked
143 | canvas2.place(x=450, y=290)
144 | img2 = (Image.open("credentialImages/" + imgList[num]))
145 | img2 = img2.resize((90, 60), Image.ANTIALIAS)
146 | img2 = ImageTk.PhotoImage(img2)
147 | canvas2.create_image(10, 10, anchor="nw", image=img2)
148 |
149 | # Random image display from second class
150 | canvas3 = Canvas(root, width=110, height=70)
151 | canvas3.bind("",
152 | lambda event: clicked(canvas3, img_name2, event)) # binding button to check if image is clicked
153 | canvas3.place(x=600, y=290)
154 | img3 = (Image.open("credentialImages/" + imgList[num + 3]))
155 | img3 = img3.resize((90, 60), Image.ANTIALIAS)
156 | img3 = ImageTk.PhotoImage(img3)
157 | canvas3.create_image(10, 10, anchor="nw", image=img3)
158 |
159 | # Random image display from third class
160 | canvas4 = Canvas(root, width=110, height=70)
161 | canvas4.bind("",
162 | lambda event: clicked(canvas4, img_name3, event)) # binding button to check if image is clicked
163 | canvas4.place(x=750, y=290)
164 | img4 = (Image.open("credentialImages/" + imgList[num + 6]))
165 | img4 = img4.resize((90, 60), Image.ANTIALIAS)
166 | img4 = ImageTk.PhotoImage(img4)
167 | canvas4.create_image(10, 10, anchor="nw", image=img4)
168 |
169 | # login button display
170 | # calls authenticate on click with credentials as arguments
171 | login = custom_button.TkinterCustomButton(master=root, text="Log In", height=40, corner_radius=10,
172 | command=lambda: authenticate(s_image[0], password_entry.get(), user_entry.get())).place(relx=0.5, rely=0.7, anchor=CENTER)
173 |
174 | custom_button.TkinterCustomButton(master=root, text="Go Back", height=40, corner_radius=10,
175 | command=lambda: load_menu(window, root)).place(relx=0.08, rely=0.08,
176 | anchor=CENTER)
177 |
178 | window.mainloop()
179 |
180 |
181 | def start(window):
182 | create_canvas(window)
183 |
--------------------------------------------------------------------------------
/segmentedImages/circle/circle1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/segmentedImages/circle/circle1.jpg
--------------------------------------------------------------------------------
/segmentedImages/circle/circle2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/segmentedImages/circle/circle2.jpg
--------------------------------------------------------------------------------
/segmentedImages/circle/circle3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/segmentedImages/circle/circle3.jpg
--------------------------------------------------------------------------------
/segmentedImages/circle/circle4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/segmentedImages/circle/circle4.jpg
--------------------------------------------------------------------------------
/segmentedImages/order.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HxnDev/Graphical-Password-Authentication-System/bfa74561c6106adf216381c22ba6f425b58b5f62/segmentedImages/order.jpg
--------------------------------------------------------------------------------
/segments.py:
--------------------------------------------------------------------------------
1 | import tkinter
2 | from tkinter import *
3 | import custom_button
4 | import main_menu
5 |
6 | import utils
7 | from PIL import ImageTk, Image
8 | import random
9 |
10 |
11 | def load_menu(window, frame):
12 | frame.pack_forget()
13 | main_menu.start(window)
14 |
15 |
16 | def start(window):
17 | window.title("Graphical Authentication System")
18 | window.geometry("1280x600")
19 |
20 | segments_frame = Frame(window, height=600, width=1280)
21 | segments_frame.pack(fill='both', expand=1)
22 |
23 | label = Label(segments_frame, text="Please select the pictures in correct order", font=('Calibri', 20))
24 | label.pack(padx=400, pady=10)
25 |
26 | ## Draw order image
27 |
28 | canvas = Canvas(segments_frame, width=300, height=250)
29 | canvas.bind("", utils.callback)
30 | img = (Image.open("segmentedImages/order.jpg"))
31 | img = img.resize((300, 250), Image.ANTIALIAS)
32 | img = ImageTk.PhotoImage(img)
33 | canvas.create_image(10, 10, anchor=NW, image=img)
34 | canvas.pack(padx=10, pady=10)
35 |
36 | imgList = utils.getSegmentedImages("circle")
37 | random.shuffle(imgList)
38 | imgClickData = []
39 |
40 | for imgPath in imgList:
41 | var = utils.imageClick(imgPath)
42 | imgClickData.append(var)
43 |
44 | # Draw shuffled segments
45 |
46 | canvas2 = Canvas(segments_frame, width=200, height=150)
47 | canvas2.bind("", imgClickData[0].clicked)
48 | canvas2.place(x=100, y=400)
49 | img2 = (Image.open(imgList[0]))
50 | img2 = img2.resize((200, 150), Image.ANTIALIAS)
51 | img2 = ImageTk.PhotoImage(img2)
52 | canvas2.create_image(10, 10, anchor=NW, image=img2)
53 |
54 | canvas3 = Canvas(segments_frame, width=200, height=150)
55 | canvas3.bind("", imgClickData[1].clicked)
56 | canvas3.place(x=400, y=400)
57 | img3 = (Image.open(imgList[1]))
58 | img3 = img3.resize((200, 150), Image.ANTIALIAS)
59 | img3 = ImageTk.PhotoImage(img3)
60 | canvas3.create_image(10, 10, anchor=NW, image=img3)
61 |
62 | canvas4 = Canvas(segments_frame, width=200, height=150)
63 | canvas4.bind("", imgClickData[2].clicked)
64 | canvas4.place(x=700, y=400)
65 | img4 = (Image.open(imgList[2]))
66 | img4 = img4.resize((200, 150), Image.ANTIALIAS)
67 | img4 = ImageTk.PhotoImage(img4)
68 | canvas4.create_image(10, 10, anchor=NW, image=img4)
69 |
70 | canvas5 = Canvas(segments_frame, width=200, height=150)
71 | canvas5.bind("", imgClickData[3].clicked)
72 | canvas5.place(x=1000, y=400)
73 | img5 = (Image.open(imgList[3]))
74 | img5 = img5.resize((200, 150), Image.ANTIALIAS)
75 | img5 = ImageTk.PhotoImage(img5)
76 | canvas5.create_image(10, 10, anchor=NW, image=img5)
77 |
78 | custom_button.TkinterCustomButton(master=segments_frame, text="Go Back", height=40, corner_radius=10,
79 | command=lambda: load_menu(window, segments_frame)).place(relx=0.08, rely=0.08,
80 | anchor=CENTER)
81 |
82 | while True:
83 | window.update_idletasks()
84 | window.update()
85 |
86 | if utils.checkAllClicked(imgClickData):
87 | sortedClickList = sorted(imgClickData)
88 |
89 | if (sortedClickList[0].id == 1) and (sortedClickList[1].id == 2) and (sortedClickList[2].id == 3) and (
90 | sortedClickList[3].id == 4):
91 | utils.create_popup(msg="Authenticated :)", font="Gabriola 28 bold")
92 | else:
93 | utils.create_popup(msg="Go Away Robot >_<", font="Gabriola 28 bold")
94 |
95 | utils.setAllUnclicked(imgClickData)
96 |
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import datetime
3 | from tkinter import *
4 | from tkinter.ttk import *
5 | from PIL import ImageTk, Image
6 |
7 |
8 | def callback(event):
9 | print("clicked at", event.x, event.y)
10 |
11 |
12 | def getSegmentedImages(shape):
13 | parentDir = "segmentedImages/" + shape
14 | imagePaths = os.listdir(parentDir)
15 | imagePaths = [parentDir + "/" + _path for _path in imagePaths]
16 | return imagePaths
17 |
18 | def getObscuredImages():
19 | imagePaths = os.listdir("obscuredImages")
20 | return imagePaths
21 |
22 | def getGarbledImages():
23 | imagePaths = os.listdir("garbledImages")
24 | return imagePaths[:-1] # last file is txt file, don't need thats
25 |
26 |
27 | def getCredentialImages():
28 | imagePaths = os.listdir("credentialImages")
29 | return imagePaths[:-1] # last file is txt file, don't need thats
30 |
31 | class customImage:
32 | def __init__(self, path, width=200, height=150):
33 | self.path = path
34 | self.img_width = width
35 | self.img_height = height
36 |
37 | def draw(self, window, c_width=200, c_height=150, img_x=0, img_y=400):
38 | # Create a canvas
39 | canvas = Canvas(window, width=c_width, height=c_height)
40 | canvas.place(x=img_x, y=img_y)
41 |
42 | # Load an image in the script
43 | img = Image.open(self.path)
44 |
45 | # Resize the Image using resize method
46 | img = img.resize((self.img_width, self.img_height), Image.ANTIALIAS)
47 | img = ImageTk.PhotoImage(img)
48 |
49 | # Add image to the Canvas Items
50 | canvas.create_image(10, 10, anchor=NW, image=img)
51 |
52 | return canvas
53 |
54 |
55 | class imageClick:
56 | def __init__(self, path):
57 | self.id = int(path[-5])
58 | self.path = path
59 | self.isClicked = False
60 | self.timeClicked = None
61 |
62 | def clicked(self, event):
63 | self.isClicked = True
64 | self.timeClicked = datetime.datetime.now()
65 |
66 | print("img id = ", self.id, " has been clicked")
67 |
68 | def __lt__(self, other):
69 | return self.timeClicked < other.timeClicked
70 |
71 |
72 | def setAllUnclicked(imgClickedData):
73 | for obj in imgClickedData:
74 | obj.isClicked = False
75 |
76 |
77 | def checkAllClicked(imgClickedData):
78 | for obj in imgClickedData:
79 | if obj.isClicked is False:
80 | return False
81 |
82 | return True
83 |
84 |
85 | def create_popup(size="500x200", msg="default", font='Arial 24', x=140, y=70):
86 | win = Tk()
87 | win.geometry(size)
88 | win.title("Message")
89 | Label(win, text=msg, font=font).place(x=x, y=y)
90 |
91 | for i in range(300000):
92 | win.update_idletasks()
93 | win.update()
94 |
95 | win.destroy()
96 | return
97 |
--------------------------------------------------------------------------------