I am deploying a stand-alone Raspberry PI based weather station and webcam. This will be visible, known and unattended for days at a time. I will be FTPing to a server and emailing daily status reports over security IP protocols. I was concerned about the unit potentially being stolen. Even in compiled Python text is still clear. There is also an ongoing project to decompile PYC files back to PY.
I posted in the Raspberry PI Forum on my challenge. Look there for some suggestions that were posted on approaches to prevent others from getting access to passwords.
In the end, I decided to use encrypted passwords. However, since at some time my Python 3.9 PYC program may be able to be decompiled, I decided to use a compiled 'C' lanquage decrypt function. I found it challenging in determining how to call and return strings between Python and C. This GIST contains a sample template on how to do this.
The sample encryption method is very simple. The ascii value of each character is added to the provide integer key to encrypt it and subtracted to decrypt it.
There is a lot of scattered information around on how to handle the Python/C interaction but no examples of how to call and return a string. In PASSWORD.C I've posted some links people can refer to.
There are a number of Python and C programs in this solution:
These were developed on a Raspberry PI using gcc 10.2.1. Compile instructions for both are included in the programs
- password.c - This program asks for the clear password and key. It calls encrypt() to display the encrypted password then decrypt() to decrypt and allow comparison with the original password. The encrypt() function is contained here but the decrypt is included from decrypt.c
- decrypt.c - This is the decrypt program used in password.c and decrypt_test.py. It is stand-alone so that it can be easily included in the compiled password and as a shared object file (decrypt.so) for decrypt_test.py
These were developed on a Raspberry PI using Python 3.9
- decrypt_test.py - This is sample framework for including the decrypting process in Python. It includes a wrapper Python to contain the specifics of calling a C return.
The following assumes that all files are in the same directory
From a terminal window
- Download the C and PY files
- Compile the password.c program to an executable according to the instructions in the program
- Compiled the decrypt.c program to decrypt.so according to the instructions in the program
From an editor or Python IDE
- Download the decrypt_test.py script.
- Find and change the call to decrypt.so to point to the correct directory
- From a termina window, run 'password' providing a password and key. I would suggest starting simple and with a low number for the key. If you receive an error of a non-readable encrypted character being created, try a different character or reduce the key number.
- Confirm that the decrypted password that comes back from 'password' matches what you entered.
- Copy the encrypted password
- Run decrypt_test.py. Enter the encrypted password and key. You should then see your original password
You can use the decrypt_test.py to craft your implementation. Keep the password program on a device other than the one where your Python program will be running. Run 'password' to create the encrypted passwords you can store as text files in your program.