I have a simple encryption module that is used to "encrypt" a text file because it contains some passwords. I only need to encrypt it because I need those passwords in my program (they are used to send an automated bug-report email), but I don't want the end-user to be able to see them.
My "encryption" function is VERY simple and straightforward: it replaces each character in the file with a two-character sequence (either two numbers, two letters, or a number and a letter - these are mapped using a dictionary). The "decryption" function simply reverses the dictionary ({v: k for k, v in _encrypt_key.items()}
), then reads the file two-characters at a time and replaces each pair with the corresponding letter. All of this works fine. The file just looks like a bunch of random numbers and letters, so it can't be "read" without the decryption algorithm by any normal end-user.
I used Cython to convert my encryption module (which is a basic Python, .py
file), to a .pyd
file, so the module itself cannot be read by a normal text-editor.
The problem occurs if the end-user has any Python experience.
For example, it is a very basic task to open the Python console, import the module, open the text file, and decrypt it using the module's "decrypt" function. To prevent this, I used the __main__
module:
import __main__ as main
if hasattr(main, '__file__'):
# define functions here
Now, it cannot be used interactively in a Python console, because the functions simply won't be defined if it is not being imported from an actual Python program.
To "secure" the key, I made the encryption key local to both functions (both the "encrypt" and "decrypt" functions have a copy of a different variable with the same data). Thus, the user cannot view the key directly.
Finally, I made sure that only certain modules can import it:
import __main__ as main
if hasattr(main, '__file__'):
path = os.path.basename(main.__file__)
if path in # tuple of specific files:
# define functions here
The only loophole I can think of is if the main program itself is edited - other than the encryption module (which is packaged as a .pyd
, so I'm not considering it as "open-source"), everything is open-source. If the end-user knows any Python, (s)he can simply open the main program and add a single line, which would show the passwords: print(EXTRA_DATA)
.
I thought of one way to prevent this:
from __future__ import print_function
print = lambda *args: None # prevent any printing, since my program itself doesn't require it
Of course, the user could always remove this, so it doesn't really fix it.
So, my overall questions are: Can I make this any more secure (make the data and module inaccessible by end-users), and can I prevent any way to print variables in my main program? I want to keep it as open-source if possible.