Inspiration

Data Security is a major concern nowadays. Privacy being basic human right is often exploited over the internet. Like a major attack by NSO on highly influential people using Pegasus Spyware. Rather than uploading sensitive files on any cloud/local Storage, user can add another layer of security by encrypting it.

What it does

The application registers the user and assigns a key which is encrypted by users password and the user data is stored in database. After Registration user can encrypt and decrypt his/her folders. For Encryption/Decryption user is asked for username and password. After the Authentication of User the server decrypts the key assigned to user and sends that key to the client application which is used to decrypt the folders.

Approach

Our first and the major challenge was to find the best approach. After brainstorming for some time, our team came up with 4 approach's:

Approach

The First Approach was to store the encrypted key locally, the major disadvantage is that the user has to maintain the encrypted key, and if the hacker manages to compromise the machine, then hacker can easily find the encryption key, and decrypt the files.

The Second Approach was Store the Encryption key at server side, here the disadvantage was that the hacker with the files can compromise the server side and get not only the key of the user but also the key of every other user which jeopardize their security.

The Third Approach was to store the encryption key locally, and encrypt that key using a public key, and private key is store at the server side which can be retrieved using user authentication. Here again the main disadvantages if that user has to maintain the key.

The Fourth Approach was to store the key at the server side which would be encrypted by user password using the AES algorithm, the only disadvantage we could think was weak password which would be applicable to all the approach's.

From the above points, we came to a conclusion that the Fourth approach is the best approach, as the key is not stored locally, therefore the user does not have to worry about it and user can upload the file to cloud, can he can simple decrypt the key on any laptop using our desktop application, which makes it convenient for transferring the file or accessing it on any other laptop.

Flow Chart

General Flow Chart

General Flow Chart

Encryption Flow Chart

Encryption Flow Chart

Decryption Flow Chart

Decryption Flow Chart

How we built it

Desktop Application

The Desktop is built using Electron JS and a python-shell library to to run the encryption and decryption scripts.

Server Application

In our server side, we used nodejs for our backend API, it is used for creating, verifying the user, and for database we use firebase, and we hosted our backend on heroku.

Encryption

All the files in the selected folder and all the subfolders are scanned for and their name and location is stored in filenames array and file_location array respectively.

os.chdir(path)
filenames = []
file_location = []
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        file_location.append(path+root[1::])
        filenames.append(name)
for i in range(0, len(file_location)):
    decrypt(filenames[i], file_location[i],key)

In this function, we first parse the extension from filename and check if the extension is supported, if the extension is supported then it open the file in binary and encrypted the data, the encrypted data is written back in the file and after that the filename is encoded using "rename_file" function.

def encrypt(filename,path,key1): extension = filename.split(".")[len(filename.split(".")) - 1] if(extension not in supported_extensions): return try: os.chdir(path) with open(filename, 'rb') as f: data = f.read() fernet = Fernet(key(key1)) encrypted = fernet.encrypt(data)

        try:
            with open(filename, 'wb') as f:
                f.write(encrypted)

        except:
            print("ERROR: Cannot Write in the file",path,filename)
            return
    try:
        os.chdir(path)
        encrypted_filename = rename_file(filename)
        os.rename(filename,encrypted_filename)

    except:
        print("ERROR: Cannot Rename the File",path,filename)
        return
except:
    print("ERROR: Could not open the file",path,filename)
    return

Renaming of file is done to increase confidentiality inspired by enigma machine. Method of renaming is inspired by Enigma Code For renaming the extension we first do the ord sum of all the characters present in the extension and we take all possible letter which are valid for file name and try out all combination's of all that letter to achieve the same ord, once we get the same ord sum then we set the extension as the new encrypted extension.

def rename_file(filename): encrypted_name = "" for j in filename.split(".")[0]: if j in alpha: encrypted_name+=new[alpha.index(j)] else:encrypted_name+=j

extension_sum = 0
for i in filename.split(".")[len(filename.split(".")) - 1]:
    extension_sum += ord(i)

no_of_letters_needed = 1

valid_numbers = [i for i in range(33,126)]
invalid_numbers = [34,42,47,58,60,62,63,92,124]
for i in invalid_numbers:
    valid_numbers.remove(i)

new_extension = ""
while(True):
    if(extension_sum > 125*no_of_letters_needed):
        no_of_letters_needed+=1
    random_select_numbers = random.sample(valid_numbers,no_of_letters_needed)
    if(sum(random_select_numbers) == extension_sum):
        for i in random_select_numbers:
            new_extension += (chr(i))
        if(new_extension in supported_extensions):
            new_extension = ""
        else:
            break

value = encrypted_name + "." + new_extension
return value

Decryption

All the files in the selected folder and all the subfolders are scanned for and their name and location is stored in filenames array and file_location array respectively.

os.chdir(path)
filenames = []
file_location = []
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        file_location.append(path+root[1::])
        filenames.append(name)
for i in range(0, len(file_location)):
    decrypt(filenames[i], file_location[i],key)

In this the function, filename is parsed to get the extension, and we first check if the extension is supported , if it is not in supported extension then it opens the file in binary and the data is decrypted by the given key, if the data is decrypted, then we rewrite the data back in the file, as during encryption we rename the file, therefore during decryption we again rename the file to get the original file name suing rename_file function

def decrypt(filename,path,key1): try: os.chdir(path) if(filename.split(".")[len(filename.split(".")) - 1] in supported_extensions): return

    with open(filename, 'rb') as f: 
        data = f.read()
        fernet = Fernet(key(key1))
        try:
            decrypted = fernet.decrypt(data)
            try:
                with open(filename, 'wb') as f:
                    f.write(decrypted)
            except Exception as e:
                print("ERROR: File cannot be written",path,filename)
        except Exception as e:
            print("ERROR: Invalid Key, file cannot be decrypted",path,filename,key1)
            return
    try:
        os.chdir(path)
        decrypted_filename = rename_file(filename)
        os.rename(filename,decrypted_filename)

    except:
        print("ERROR: Cannot Rename the File",path,filename)
        return

except Exception as e:
    print("ERROR: Could not open the file",path,filename,e)
    return  

In this function the encoded file name is decode by reversing the enigma code, and for extension, we take the ord sum of all letters present in extension and we match the value in "extension_value" dictionary and get the original extension back. On getting the original filename and extension back, we rename the file.

def rename_file(filename): decrypted_name = "" for j in filename.split(".")[0]: if j in new: decrypted_name+=alpha[new.index(j)] else:decrypted_name+=j

extension_sum = 0
for i in filename.split(".")[len(filename.split(".")) - 1]:
    extension_sum += ord(i)

if(extension_sum in extension_value):
    return decrypted_name+"."+extension_value[extension_sum]
else:
    return filename

Challenges we ran into

Approach

Selecting the best approach for our problem, after brainstorming we were able to figure out 4 approach and we selected the best out of them.

Electronjs

It was challenging to work with new and unfamiliar technology.

Encryption

We were not that familiar with encryption, we had to first understand what is encryption in depth and how it can be implemented for our project.

Accomplishments that we're proud of

We are very proud of our approach, and also about our desktop app as well as our encryption and decryption logic, as for desktop app, we learned how to use electronjs and created a fully functional desktop app with exception handling in just 2 days. We also learned what is encryption how it works, and we create a fully functional encryption and decryption script in python during the duration of hackathon.

What we learned

Our team learned how to work and co-ordinate with each other, how to brainstorm and get the best possible solution for the problem. Our team learned new technology like electornjs, and we learned the concept of encryption and the implementation of various encryption algorithms.

What's next for Keep it safe

We are going to continue our development on our product, we will think of more approach's which might be better than our current approach, we will look into other encryption algorithm's which would be better than our current encryption algorithm. We would make a fully finished product and will make it open source so that other people can contribute in it and which help's to keep our data save

Share this project:

Updates