Encrypt a Library Linux - python

I've created my own Python library on my Raspberry Pi 3 called myLibrary.py, and in another program called example.py, I use this library:
import myLibrary
I need to hand this Pi over to someone else, but I want the library encrypted. I've tried GnuPG, bcrypt, and ccrypt.
My issue is that the program no longer runs once the library is encrypted, I can an error saying "No module named myLibrary
How can I encrypt the library and still be allowed to use it in my program?
Thanks

Python has to read the library to run it, and to read it correctly, it must be decrypted. Otherwise how do you expect python to be able to run encrypted code?
If you distribute an encrypted library, you have to add code to decrypt the library first before importing it. Otherwise there is no way python can read encrypted data and know what it means - that is the whole point of cryptography!

If you are trying to hide the source, it may be difficult to do so. You may want to find out whether it is worth to go through such effort.
PYC only distribution: One of the options, I don't personally like this option, is to distribute only the Bytecode i.e. just by distributing only .pyc files. But it will take only few more steps for anyone to deconstruct the bytecode from those files into a human readable format.
PyInstaller: The second option may be to use the PyInstaller and you may want to read the documentation here.
PyInstaller
Use Obfuscation: There may be some obfuscation tools for Python and you can look at them to obfuscate. You may want to read stackoverflow question here:
Obfuscating Python code
SaaS: Last but not the least if you really want to protect the code, host it in a server and give access to your service. It is so called software as a service(SaaS).

Of course it wont run, the file contents stop making sense to anyone trying to read once you encrypt it (well unless they know it is encrypted and have the key to decrypt it).
The file cannot be encrypted, it has to make sense at least to the Python interpreter.
What you can do to protect the file is obfuscate it. There are several Python Obfuscators around, just Google the term.

Related

How to protect my Python code before distribution?

I have written a python code which takes an input data file, performs some processing on the data and writes another data file as output.
I should distribute my code now but the users should not see the source code but be able to just giving the input and getting the output!
I have never done this before.
I would appreciate any advice on how to achieve this in the easiest way.
Thanks a lot in advance
As Python is an interpreted language by design; and as it compiles code to a bytecode (- which doesn't help the fact you're trying to conceal it, as bytecodes are easier to reverse -) there's no real secure way to hide your source code whereby it is not recoverable, as is true for any programming language, really.
Initially, if you'd wanted to work with a language that can't be so easily reversed- you should've gone for a more native language which compiles directly to the underlying architecture's machine code which is significantly harder to reproduce in the original language let alone read due to neat compiler optimizations, the overhead given by CISC et cetera.
However, some libraries that do convert your source code into an executable format (by packing the Python interpreter and the bytecode alongside it) can be used such as:
cx_Freeze - for freezing any code >=Python 2.7 for any platform, allegedly.
PyInstaller - for freezing general purpose code, it does state additionally that it works with third-party libraries.
py2exe -for freezing code into Windows-only executable format.
Or you might consider a substitute for this, which is code obfuscation which still allows the user to read the source code however make it near-to-impossible to read.
However, an issue brought up with this is that, it'd be harder for code addition as bad code obfuscation techniques could make the code static. Also, on the latter case, the code could have overhead brought by redundant code meant to fool or trick the user into thinking the code is doing something which it is not.
Also in general it negates the standard practice of open-source which is what Python loves to do and support.
So to really conclude, if you don't want to read everything above; the first thing you did wrong was choose Python for this, a language that supports open source and is open source as well. Thus to mitigate the issue you should either reconsider the language, or follow the references above to links to modules which might help aide basic source code concealment.
Firstly, as Python is an interpreted language, I think you cannot completely protect your Python code, .pyc files can be uncompiled to get back .py files (using uncompyle6 for example).
So the only thing you can do is make it very hard to read.
I recommend to have a look at code obfuscation, which consists in making your code unreadable by changing variables/function names, removing comments and docstrings, removing useless spaces, etc. Pyminifier does that kind of things.
You can also write your own obfuscation script.
Then you can also turn your program into a single executable (using pyinstaller for example). I am pretty sure there is a way to get .py files back from the executable, but it just makes it harder. Also beware of cross-platform compatibility when making an executable.
Going through above responses, my understanding is that some of the strategies mentioned may not work if your client wants to execute your protected script along with other unprotected scripts.
One other option is to encrypt your script and then use an interpreter that can decrypt and execute it. It too has some limitations.
ipepycrypter is a suite that helps protect python scripts. This is accomplished by hiding script implementation through encryption. The encrypted script is executed by modifed python interpreter. ipepycrypter consists of encryption tool ipepycrypt and python interpreter ipepython.
More information is available at https://ipencrypter.com/user-guides/ipepycrypter/
One other option, of course, is to expose the functionality over the web, so that the user can interact through the browser without ever having access to the actual code.
There are several tools which compile Python code into either (a) compiled modules usable with CPython, or (b) a self-contained executable.
https://cython.org/ is the best known, and probably? oldest, and it only takes a very small amount of effort to prepare a traditional Python package so that it can be compiled with Cython.
http://numba.pydata.org/ and https://pythran.readthedocs.io/ can also be used in this way, to produce Python compiled modules such that the source doesnt need to be distributed, and it will be very difficult to decompile the distributable back into usable source code.
https://mypyc.readthedocs.io is newer player, an offshoot of the mypy toolkit.
Nuitka is the most advanced at creating a self-contained executable. https://github.com/Nuitka/Nuitka/issues/392#issuecomment-833396517 shows that it is very hard to de-compile code once it has passed through Nuitka.
https://github.com/indygreg/PyOxidizer is another tool worth considering, as it creates a self-contained executable of all the needed packages. By default, only basic IP protection is provided, in that the packages inside it are not trivial to inspect. However for someone with a bit of knowledge of the tool, it is trivial to see the packages enclosed within the binary. However it is possible to add custom module loaders, so that the "modules" in the binary can be stored in unintelligible formats.
Finally, there are many Python to C/go/rust/etc transpilers, however these will very likely not be usable except for small subsets of the language (e.g. will 3/0 throw the appropriate exception in the target language?), and likely will only support a very limited subset of the standard library, and are unlikely to support any imports of packages beyond the standard library. One example is https://github.com/py2many/py2many , but a search for "Python transpiler" will give you many to consider.

Python Pyinstaller - How to Patch Program That I Have Built?

I have built a keyword search tool in Python, and then converted it into an .exe format with Pyinstaller, so people at my workplace could use it without having to install Python.
I have sent this around to everyone by e-mail in a RAR file which they have then saved to their desktops.
I am thinking of some potential tweaks I might make to it, but I do not want to have to keep on sending them the full program every time I decide I want to change something.
So, the question is, is there a way that I can send a patch file to upgrade the program instead? What should I be looking at?
Thanks in advance!
You just can't. Compiling a program freezes it, meaning that it cannot be modified.

how to distribute a package with out exposing the source code in python?

Consider that I have a package called "A" consisting of several modules and also nested packages. Now, I want to distribute this package to user and I do not want user to see my code at all. I heard that ".pyc" can be de-compiled. So, I am just wondering what could be the other alternatives for this problem.
It would be great if someone gives some ideas in this regard.
You actually have few options. First, you can compile your code into pyc files. However, this can be circumvented with the disassembler library dis, but this requires a lot of technical know-how. You can also use py2exe to package it as an exe file; this converts the pyc file into an exe file. This can still be disassembled but adds an extra layer. You also have a few encryption solutions; for example you can use pyconcrete to encrypt your imports until they are loaded into memory. You can also just encryption the entire application, then ship the decrypter and launcher with it as a C/C++ application (or any other compiled language). Lastly, if you are comfortable with getting python to run custom C/C++ code, you can also put your private code into a DLL or SO and call it directly for the script.
Python is an interpreted language. That means that if you want to distribute pyc files you'll have to have them run on the same OS/architecture as yours or you'll run into subtle problems. That, and the fact that most code can be decompiled to some degree, would urge me to rethink your use case.
Can you rethink your package as a service instead?

Trouble with pySerial deployment

I have a custom python script that depends on MinimalModbus and the pySerial library. I am trying to deploy it to a router which runs a python interpreter.
MinimalModbus is just a single .py file which is trivial to deploy. However, the pySerial library appears to be much more robust. It looks like several python files that work together to "automatically select the appropriate backend".
Does one have to "install" pySerial in order to use it? Or is there some way to extract just the pertinent files/dependencies for a given OS?
I don't know what all is performed when you run pySerial's setup.py (e.g. files copied?). I don't know if it will work for this particular type of deployment. I was hoping to just include specific files.
Any help will be appreciated.
We are using Python version 2.6.
Update:
I basically took the "installed" files from the /site-packages/serial folder on my development box and uploaded them to the device. This got me a bit further; however, I am now getting the following error:
Line ~273 of serialposix.py , it's calling:
self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
Why would it not be able to find the os.open routine?
Update 2:
Further simplifying the problem, my script now consists of something as simple as the following, and it still fails with the same error:
import os
serfd = os.open("/com/0", os.O_RDWR | os.O_NONBLOCK)
Under Python Standard Modules with Digi-Specific behavior, they make the following comment about the os module:
Use of the os module in Digi devices is currently very limited. The primary purpose in exposing it is to allow access to the serial ports, which are presented as nodes in the file system. Serial ports are available as files with the path in the form /com/0 with the zero replaced by the zero-based index of the serial port to control.
In addition, both of their sample applications use the os.open routine for serial communication.
I would have expected to maybe see an error such as: OSError: [Errno 2] No such file or directory: '/com/0', but this is not the case. Python can't even locate the os.open routine.
Would you expect the os.py file to have a def open(...) routine defined?
After opening a support case with the manufacturer of this router, it turns out that the os.open function is not supported on this device. However, the device does support io.open which I believe is similar. More importantly, I learned that the manufacturer provides their own "pyserial" implementation specifically designed to work on the device's operating system. Internally, it looks like they've switched out the calls to use io.open equivalent.
having had a look through the source files, i believe that it is entirely python based, and when it installs it copies the files across to the site-packages folder.
having said that it appears that you would need several of the source files in order for it to work, and if you were simply copying them across you may need to modify their imports to ensure they work properly.
eg for linux you would need the serialposix.py file and the serialutil.py
you may need more than just this, but i have only had a quick look through.
but at the top of serialposix.py there is a line:
from serial.serialutil import *
this would need to be changed to:
from serialutil import *
and there may be other such changes to make.
but ultimately this seems to use ctypes to do the hard work talking to the underlying OS, so you should be able to make it work.
UPDATE:
to explain why it is calling os.open, on most platforms serial ports are treated almost like files, in tthat the return a "file like" handle, the idea behind pyserial is to abstract operating system level differences away to create a single easy to interface to these, but ultimately it is still treated as a file like handle by the OS.
just for clarification could you let us know what version of pyserial you are using? as the line number you quoted and what i'm looking at don't match.
i suspect the main reason you are having difficulty is the zip nature of the python deployment you are using, but i do find it hard to believe that OS is not included in it, have you checked the OS python file in the ZIP or is it a compiled python file?
UPDATE 2:
haveing looked at the documentation for the distro you are using i would suggest you have a read through the following:
Python Standard Modules with Digi-Specific Behavior
where is states that some funtionality is limited on these devices, it also gives a method by which you can test if it is supported by telnet/SSH into the device and trying it on the python command line.
also, while it is anot as neat and easy to use as the pyserial module, i suggest you give this a read too:
Digi Serial Port Access

Python4Delphi-powered program, how to deploy it?

My Delphi program uses Python4Delphi, and the Python script uses some standard libs. When deploying my program I don't want an entire Python installation, and it must work with python27.dll. What are the minimal set of necessary files? The document in Python4Delphi is dated and it's not clear to me...
Thanks for your help.
When I did this, I made the list myself, of what I needed for my embedded python application to work.
I remember this worked with python15.dll:
PythonXX.dll should work, without any other external files other than the Visual C++ Runtime DLLs, which require a side-by-side manifest (see the p4d wiki page) to work.
If you want to IMPORT something, then you need to ship it and anything it depends on. That means, either you pick part of the python standard libraries you want, or you pick all of it. There is no way you need all of Python's standard libraries. But I wouldn't want to live without OS and a a few other key ones. BUt the decision is yours.

Categories