-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
685 lines (514 loc) · 17.9 KB
/
main.cpp
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
/*
Password Shield
*/
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib> // exit function prototypes
#include <ctime> // for using time
#include <fstream> // contains file stream processing types
#include <numeric> // for using gcd()
#include <conio.h> // for using getch()
#include <iomanip>
#include "clipboardxx/clipboardxx.hpp" // for copy pasting to clipboard external library header
using namespace std;
// RSA Algorithm Begin
unsigned PUBLIC_KEY;
unsigned PRIVATE_KEY;
unsigned N;
/*
* keyGeneration() generates public and private key using RSA Algorithm
*/
void keyGeneration(){
unsigned p = 97; // first prime number
unsigned q = 101; // second prime number
N = p * q; // n = p*q
unsigned phi_n = (p-1) * (q-1); // phi_n = (p-1) * (q-1)
unsigned e; // 1 < e < phi_n; e should be coprime with phi_n
unsigned d; // (e*d) mod phi_n = 1
// public key generation
unsigned i = 2;
while(gcd(i,phi_n) !=1) {
i++;
}
e = i;
PUBLIC_KEY = e;
// private key generation
unsigned k = 1;
while(((k*phi_n)+1) % e != 0) {
k++;
}
d = ((k*phi_n)+1)/e;
PRIVATE_KEY = d;
}
/*
* encrypt() takes an unsigned number and converts it to encrypted number
*/
unsigned long long int encrypt(unsigned message){
unsigned e = PUBLIC_KEY;
unsigned long long int encrypted_text = 1;
while(e--){
encrypted_text *= message;
encrypted_text %= N;
}
return encrypted_text;
}
/*
* decrypt() takes an unsigned number and decrypts it to the original letter
*/
unsigned long long int decrypt(unsigned encrpyted_text)
{
unsigned d = PRIVATE_KEY;
unsigned long long int decrypted = 1;
while (d--) {
decrypted *= encrpyted_text;
decrypted %= N;
}
return decrypted;
}
/*
* takes password as a parameter
* encrypts it using public key
* returns an unsigned vector which is the encrypted text
*/
vector<unsigned>encoder(string message){
vector<unsigned> form;
for(auto &letter: message){
form.push_back(encrypt((unsigned)letter));
}
return form;
}
/*
* takes unsigned vector of encrypted text which was generated by encoder()
* decrypts it using private key
* returns the original password as a string
*/
string decoder(vector<unsigned> encoded){
string s="";
for (auto &num: encoded){
s+=decrypt(num);
}
return s;
}
// RSA Algorithm End
/*
* encrypt_password() encrypts the password into encrypted string and returns it
* string is returned so that it can be written in password.txt
*/
string encrypt_password(string password){
vector<unsigned> encrypted_password = encoder(password); // encrypting the password
string encrypted="";
for(auto &p: encrypted_password){
encrypted += to_string(p);
encrypted += ':';
}
return encrypted;
}
/*
* decrypt_password() decrypts the password into original password from encrypted string and returns it
* the original password is returned as an unsigned vector
* the vector is later converted into string to print in the terminal/console
*/
vector <unsigned> decrypt_password(string encrypted_password){
// converting encrypted password string to unsigned vector for decryption
vector<unsigned> tovec;
for(int i=0;i<encrypted_password.length();i++){
string ns;
while(encrypted_password[i] != ':') {
ns += encrypted_password[i];
i++;
}
tovec.push_back((unsigned)stoi(ns));
}
return tovec;
}
const string MASTER_PASSWORD = "1234"; // Default MASTER_PASSWORD
/*
* check_masterPass() return a boolean value
* this function check MASTER_PASSWORD which is already set in the program
* with the user typed password (master_password) and returns value with that accord
* this function also uses password masking. so when you type a password * is shown in the console
* instead of the typed password
* password masking is achieved by using conio.h header file
* this can also be achieved by using win32 api or ncurses library or writing the getch() manually
*/
bool check_masterPass(){
// asking user to type master password
cout << "Type your Master Password to Access the program: ";
string master_password;
const char BACKSPACE = 8; //ASCII code for BACKSPACE Key
const char ENTER = 13; //ASCII code for ENTER Key
char c; //initialize character
// password masking begin
while ((c = getch()) != ENTER) // keep taking character unless enter is pressed
{
if (c == BACKSPACE) // if backspace is pressed
{
if (master_password.length() != 0) // checks if characters are already typed or not
{
cout << "\b \b"; // first moves the cursor back one place and then writes a space to erase the character
master_password.resize(master_password.length() - 1); //resize the length of master_password
}
}
else
{
master_password.push_back(c); // push back to string master_password for later comparison
cout << '*'; // print * instead of the typed character
}
}
cout << endl;
// password masking end
// comparing user typed password with hardcoded password
if(master_password == MASTER_PASSWORD) {
return true;
}
return false;
}
/*
* clear_display() is a function that clears the terminal/console by sending
* appropiate system command for respective operating system
* it can detect Windows and Linux operating system
*/
void clear_display()
{
#ifdef _WIN32 // for detecting windows 32 or 64 bit system
system("cls");
#elif __linux__ // for detecting linux
system("clear");
#endif
}
/*
* intro_art() reads from intro_art.txt which contains ascii art
* output the contents line by line in terminal / console
*/
void intro_art(){
ifstream intro_file("intro_art.txt", ios::in);
if(!intro_file) {
cout << "PASSWORD MANAGER" << endl;
cout << "----------------" << endl;
return;
}
string line;
while(getline(intro_file, line)){
cout << line << endl;
}
intro_file.close();
}
/*
* menu() design for the password manager menu
* it represents all the options that is available
*/
void menu() {
cout << internal << "-----------------------" <<endl;
cout << "|" << setw(11) << "Menu" << setw(11) << "|" << endl;
cout << "-----------------------\n" <<endl;
cout << "1. Generate Password" << endl;
cout << "2. Store Password" << endl;
cout << "3. Find Password"<<endl;
cout << "4. Change Password" << endl;
cout << "5. Delete an Entry" << endl;
cout << "6. View Saved Passwords" << endl;
cout << "q. Quit"<<endl;
cout << endl;
cout << "Enter Your Choice: ";
}
/*
* store_password() stores password in password.txt
* it stores encrypted_password that is encrypted using RSA Algorithm
*/
void store_password(string &default_password) {
clear_display();
ofstream pass_file("password.txt", ios::app);
// checks if file exists
if(!pass_file){
cerr << "Could not open the password file" << endl;
exit(EXIT_FAILURE);
}
cout << "Enter the following informations to store password" << endl;
cout << "----------------------------------------------------\n"<< endl;
string website, username_email, password;
cout << "Enter Website: ";
cin >> website;
cout << "Enter Username/Email: ";
cin >> username_email;
if(!default_password.empty()) {
password = default_password;
}
else {
cout << "Enter Password: ";
cin>> password;
}
cout << endl;
// encrypting the password into encrypted_password
string encrypted_password = encrypt_password(password); // calling encryp_password fundtion that converts password to encrypted password string
pass_file << website << " " << username_email << " "<< encrypted_password << endl;
pass_file.close();
cout << "Password is stored...\n" << endl;
}
/*
* generate_password() generates a pseudo random password
* generated password can be saved in the file
* generated password automatically is saved to clipboard by using clipboardxx library
*/
void generate_password() {
clear_display();
string random_str = "0123456789"
"!@#$%^&*"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
srand(time(NULL));
int random_str_len = random_str.size();
// asks user for password size (how long the password will be)
cout << "Enter Password Length (In Integer): ";
int password_length;
cin >> password_length;
cout << "\nGenerating Password.......\n" <<endl;
// Generating password
string new_pass;
while(password_length--){
new_pass+=random_str[rand()%random_str_len];
}
cout << new_pass << endl <<endl;
// copy to clipboard
clipboardxx::clipboard clip; // creating clipboard object from external library clipboardxx
clip << new_pass; // To copy the generated password to clipboard
// asks the user to save the password in password.txt file
cout << "Do you want to save the password (Y or N): ";
char choice;
cin>>choice;
if(choice == 'Y' || choice == 'y'){
store_password(new_pass);
}
cout << endl;
}
/*
* find_password() finds the password by using website or username/email
* this function reads from password.txt, decrypts the password and output it to terminal/console
*/
void find_password() {
clear_display();
ifstream pass_file("password.txt", ios::in);
// checks if file exists
if(!pass_file){
cerr<< "Could not open the password file" <<endl;
exit(EXIT_FAILURE);
}
// asks user by which method want to find the password
cout <<"Choose A Method To Find Password" <<endl;
cout << "--------------------------------\n" <<endl;
cout << "\nFind Password by:\n" << endl;
cout << "1. Username/Email" << endl;
cout << "2. Website" << endl;
cout << "\nEnter Your Choice (1 or 2) : ";
char choice;
cin>> choice;
string username_email, website, encrypted_password,find_by;
if(choice == '1'){
cout << "\nType Username/Email: ";
cin>> find_by;
}
else if(choice == '2') {
cout << "\nType Website: ";
cin>> find_by;
}
else {
cout << "Invalid choice....." << endl;
cout << "Please type 1 or 2" << endl;
find_password();
}
cout << endl;
bool password_found = false;
while(pass_file >> website >> username_email >> encrypted_password){
if(choice == '1' && find_by == username_email) {
vector<unsigned> tovec = decrypt_password(encrypted_password); // to decrypt the password
cout << "For Website: " << website << " | ";
cout << "Password: "<< decoder(tovec) << endl;
password_found = true;
}
else if(choice == '2' && find_by == website ) {
vector<unsigned> tovec = decrypt_password(encrypted_password); // to decrypt the password
cout << "For Username/Email: "<< username_email << " | ";
cout << "Password: "<< decoder(tovec) << endl;
password_found = true;
}
}
if(!password_found) {
cout << "Password not found" <<endl;
}
cout << endl;
}
/*
* password_list() prints all the password to the terminal/console
* reads the password.txt file and decrypts the password before printing it
*/
void password_list() {
clear_display();
cout << "------------------------------------------- ";
cout << "PASSWORD LIST";
cout<< " -------------------------------------------\n"<<endl;
ifstream pass_file("password.txt", ios::in);
// checks if file exits
if(!pass_file){
cerr<< "Could not open the password file" <<endl;
exit(EXIT_FAILURE);
}
string username_email, website, encrypted_password;
int serial = 1;
cout <<left << setw(25) <<"Serial" <<setw(25) << "Website" <<setw(25) <<
"Username" << setw(25) << "Password" << endl;
while(pass_file >> website >> username_email >> encrypted_password){
vector<unsigned> tovec = decrypt_password(encrypted_password); // converts encrypted password to unsigned vector
cout <<left << setw(25) << serial <<setw(25) << website
<< setw(25) << username_email << setw(25) << decoder(tovec) << endl;
serial++;
}
cout << endl << endl;
pass_file.close();
}
/*
* change_password() changes a particular password from password.txt
* this function replaces the encrypted password by new encrypted password
*/
void change_password() {
password_list();
// asks the user for the line number the password to be changed
cout << "Which password do you want to change?" << endl;
cout << "Type the line number: ";
int line_number;
cin>> line_number;
int temp_line = line_number;
// Read the file and store the password in a variable
ifstream input_file("password.txt", ios::in);
if(!input_file){
cerr<< "Could not open the password file" <<endl;
exit(EXIT_FAILURE);
}
string username_email, website, encrypted_password;
while(input_file >> website >> username_email >> encrypted_password) {
--temp_line;
if(temp_line==0) break;
}
input_file.close();
ifstream inp_file("password.txt", ios::in);
vector<string> lines;
string line;
while(getline(inp_file,line)){
lines.push_back(line);
}
inp_file.close();
if(line_number>lines.size()){
clear_display();
cout << "Line " << line << " not in the file" << endl;
cout << "File has " << lines.size() << " lines"<<endl;
return;
}
// asks the user for new password
cout << "Type the new password: ";
string new_password;
cin>>new_password;
// opens the file in output mode inorder to rewrite it
ofstream output_file("password.txt", ios::out);
for(int i=0;i<lines.size();i++){
int pos = lines[i].find(encrypted_password); // finds the index of the old encrypted password
if(pos != string::npos && line_number -1 == i) {
// replaces the old encrypted password with new encryptes password
lines[i].replace(pos,encrypted_password.size(),encrypt_password(new_password));
}
output_file << lines[i] << endl;
}
output_file.close();
clear_display();
password_list();
cout<< "\nSuccessfully changed the password in Line "<< line_number << " to: " << new_password
<<" ...\n" << endl;
}
/*
* delete_entry() deletes a whole line from the password.txt file
* it reads from the password.txt file
* saves all the lines to a vector
* then it rewrites to password.txt file except the line to be deleted
*/
void delete_entry(){
password_list();
// asks the user which line to delete
cout << "Which entry do you want to delete?"<<endl;
cout << "Type the line number: ";
int line_number;
cin>> line_number;
ifstream input_file("password.txt", ios::in);
if(!input_file){
cerr<< "Could not open the password file" <<endl;
exit(EXIT_FAILURE);
}
vector<string> lines;
string line;
while(getline(input_file, line)){
lines.push_back(line);
}
input_file.close();
// check if invalid line number is provided
if(line_number>lines.size()){
cout << "Line " << line << " not in the file" << endl;
cout << "File has " << lines.size() << " lines"<<endl;
return;
}
ofstream output_file("password.txt",ios::out);
for(int i=0;i<lines.size();i++){
if(i != line_number - 1){
output_file << lines[i] << endl;
}
}
output_file.close();
clear_display();
password_list();
cout << "\nSuccessfully Deleted The Entry...\n" << endl;
}
// Main Function Begins
int main(){
int attempt_counter = 0;
// checking master password
while(!check_masterPass()){
if(attempt_counter>=3){
clear_display();
cout << "You have typed wrong password more than three times\n" << endl;
cout << "Please Run the program and try again......" << endl;
return -1;
}
cout << "Master Password is wrong. Try again" << endl;
attempt_counter++;
}
clear_display();
char option;
intro_art(); // to display ascii art
keyGeneration(); // Key generation for RSA Algorithm
// program will run till it is explicitly closed
do {
menu();
cin >> option;
if (option == '1'){
generate_password();
}
else if (option == '2') {
string default_password = "";
store_password(default_password);
}
else if(option == '3'){
find_password();
}
else if(option == '4'){
change_password();
}
else if(option == '5'){
delete_entry();
}
else if(option == '6'){
password_list();
}
else if(option != 'q'){
cout << "Wrong Option\nTry Entering 1 to 6 or q :)\n" << endl;
}
else {
cout << "\nQuiting...\n" <<endl;
}
}while(option != 'q'); // option for closing the program
}