What I want to do is protect a Python program from being stolen by people with no computer knowledge. I accept the inevitability of the program being pirated, all I want to do is protect it from average users.
I have come up with two ideas.
1.)Set a time restriction by checking online for the date and time. I.E. 10 days from downloaded time.
2.)Checking the IP or Name of the computer that downloaded it and make the program only runs on that computer. (to prevent friends from simply sharing the file).
The problem with both of these is that I'll need to create a .py file "on the fly" and then use something like pytoexe to make it into an .exe so that the user doesn't need to have Python installed.
The problem with the second is that to my understanding ip's change and getting the computer name is a security risk and might scare away users.
So to sum it up, here are my two questions:
1.) Is there a good way in python to only allow the program to run on that single computer?
2.) What is the best way to implement a "on the fly" creation of the exe? (I was going to host the website on my computer and learn php(?)/servers.
I have moderate c/c++ and basic html/css, java, and python experience.
Thank you for your time!
Messy business. You probably already understand that compiled does not mean encrypted.
However, if you're boss considers c-compiled as satisfactory, you can use cython to compile your python code to c-code and then gcc to compile the c-code.
Check here on how to build your setup.py script.
http://docs.cython.org/src/reference/compilation.html#compiling-with-distutils
And you can embed python using into the resulting c code using the --embed option:
# will generate the target.c
$ cython target.py --embed
Give each user a customized installer that has a unique key in it. When it runs, it contacts a server (with the key) and requests the actual program. Server-side, you check if the key is valid and if so, serve the program customized with the key, and mark the key as used. The installer saves the program somewhere the user can access it, and creates a hidden file that contains the key somewhere deep in the bowels of the computer, where the "average user" won't think of looking. When the program is run, the first thing it does is check if the hidden file exists and if it contains the correct key, and refuses to run if not.
(I am assuming that unzipping an executable and reading source code is beyond the ability of the "average user" (read: "grandma"), so using py2exe is ok.)
To avoid having to contact anything on the Internet, you could use the following way to 'dongle' your program:
Take a vital part of your program (something without which the rest won't be useful),
put it into a string,
encrypt that string symmetrically with the MAC address of the computer it shall run on,
then in your program do this:
decrypt that string with the MAC address of the current machine it runs on an and
call that decrypted string using exec.
Example with the vital part being print "hello world":
def getMyMac():
return 123456789L # for testing now
return uuid.getnode() # this would be the real thing
def strxor(s, key):
key *= len(s) / len(key) + 1
return ''.join(chr(ord(key[i]) ^ ord(s[i])) for i in range(len(s)))
def performVitalCode():
code = 'A#ZZA\x16\x15P\\]^\\\x14BYET]\x13'
# I found that code by entering:
# strxor('print "hello world"', str(getMyMac()))
realCode = strxor(code, str(getMyMac()))
exec realCode
I here used a simple xor on strings for crypting (which is not a hard cypher to crack).
Of course the user of the "allowed" computer can hand over his MAC address to the next user which then
either can patch the getMyMac() or
spoof his own MAC address; most network cards allow this.
So this is not a "safe" solution to your problem.
But if a person with just little computer knowledge gave your code to some other guy without any further information (maybe by putting it online in a forum or similar), the receiver won't be able to execute it out of the box.
Finally I need to point out that every chaining of code to a specific computer may well become a hassle for the rightful user of the code. If I'm using a program which stops working just because I switch to a different hardware (maybe just because I get a new laptop), I'm usually pissed and curse the writer of that code. You might not want to annoy your customers.
Seems like a combination of things here. Encapsulating python as others have suggested is a good way to go, for bundling. You may also consider obfuscation, as talked about here in another StackOverflow thread:
Python Code Obfuscation
Which references:
http://freecode.com/projects/pyobfuscate
As for making it so that someone can't just download your program and run it elsewhere or distribute it, how willing are you to inconvenience your end users? :)
As others have noted above, you can generate a compiled and bundled bit of code with the ID specific to the user. That way, if/when the application phones home, you can track usage.
If your end users/customers have the following requirements fulfilled:
An account with you, which they can login and check their subscription/account status
Internet connectivity from the machine running the program
You can make the installation process do the following:
Installer is NOT the full program. Generates a profile of the machine.
This profile bundled up and a hash is generated. Both are uploaded to your servers.
The hash is displayed to the end user to enter, once they have signed into their online web account.
The user installing the application submits the hash, and gets a download link and an unlock key. The key is only good for that dynamically generated download and only on that machine. The downloaded program, however, will accept a range of keys unique to itself(iteratively generated, etc).
The user can then complete the install and run their program. The program will periodically check the profile of the machine it is on, to make sure that the hash does not deviate. If it does, the program can prompt them to login to their web account to generate a new key. The new key is then used to refresh their application. This can be automated by the application, but with the internet laws and such, having the user sign into their account and perhaps agree to any updates to the EULA, would be better.
If they decide to share the program in a VM bundle, they would still need an active account to get keys.
Note, this does not prevent someone from bypassing the hash check. But for the average user, this will serve as a good way for you to deter people giving away or reselling your program.
Just bear in mind, no system is foolproof.
Related
Background
I've been working on a project that requires OTP for authentication and I've been able to get it mostly working, except for a few minor details. I've been using PyOTP to use Time-Based OTP codes sent to Google Authenticator for this.
The Issue
I've run into a problem when I'm executing the program on 2 computers. One computer is my laptop (which I have at home), and the other is my work PC.
My issue is that, whenever I am trying to authenticate the codes at work, my program returns that the codes aren't valid. They are shown as being valid at home however. I created the program on my home laptop.
Attempts to fix
I've made sure both computers and my phone's clocks were synced up before this was an idea. Timing is not an issue.
Both computers and my phone use the same "secret key", so that is not an issue.
I made a second key and linked it up with Google Authenticator along with the first key, and that didn't work (I believed the hashes may not be the same, and I believe that may still be an issue).
Hunches
I know that PyOTP does use SHA hashing (where exactly in the module, I don't know!), and I know SHA hashing doesn't produce the same hash across different devices, so I am wondering if that is the issue, that the hashes aren't the same. I also know MD5 hashing does work across devices, so it may be the case that it is the hashing that may need to be changed.
If anyone can help with this, please let me know! I will update this with the results of whatever methods are used!
If you want to understand how TOTP actually works, check out these articles. The 1st one explains the gist of it. 2nd and 3rd go into all the technical details. Link to the 1st part:
https://prezu.ca/post/2021-07-30-totp-1/
From there just click Next to get to part 2 and then Next to get to part 3.
I am writing a program in python for a school project and one of its features is that it can send emails out.
However, in order to send an email from the program, you must login to the email account meaning my password for that account is contained within a variable in the program.
Because this is for a school project, I will have to send this to people I am working with and they'll be able to read the code but I don't really want my password being openly left in a variable for them to see.
Is there any way to hide it or encrypt it so that other people can't see it?
Unfortunately, the answer is no.
This is a big security issue and a very common way for people to have programs "hacked" (they post some code on a public repository with an API key or password in it, and people can take that and do what they want with it).
Here are the most common solutions to this problem:
Use a server. This probably isn't very viable for you since it's for a school project, but in larger project, we'd typically send a request to our server (which knows the password), and it would send it form there. Code on a server (if protected correctly) is considered moderately safe. Even still, it would be very bad design to put the password in the code. Since the end user won't see the server's code, they won't be able to get that password. Note that this is an oversimplification and there's more to securing a server than just what I've mentioned.
Use environment variables. Environment variables can be set in your terminal and store the information on your own computer, not in the program. However, for it to work, each user would need to set their environment variables in their own terminal, and if you're trying to share an account, this is not the way to go because then you'd have to give them the password anyways. This is a good article that discusses environment variables and how to set them. In python, you can get the variable using the os module (os.environ["ENV_VARIABLE_NAME"]).
A general rule of thumb is never ever put anything in your source code (for the client side) that you wouldn't want the whole world seeing. It is possible to get this information out of the code and can cause big issues down the road.
Let me know if you have any other questions!
I have something in my clipboard, and I'd like to run a python script that invokes CTRL+V as if it was pressed on the keyboard, and pastes the clipboard's content to the current focused window (say chrome). Any idea how to do that?
You have an X-Y problem.
What you want to accomplish is programmatically take data from one program (where you hit cntrl-V) and place it into another arbitrary program (chrome).
There are two ways to do that:
First
You can either set the programs up to have a data exchange mechanism such as a system pipe, or a network connection. This requires some API for data exchange to be already included in the program or access to the source so you might add one. There are very specific channels for cross program data exchange and you wont do well to try to circumvent them. Program A cant just say
get_program_b().get_text_box().add(clip_board);
That would be a violation of Process Isolaton and an OS like windows is written expressly to make it impossible. Some programs are designed to take input from other programs.
popen.open('mysql -e "ISNERT INTO table (a) VALUES ('4')")
Chrome is not one of those programs, chrome avoids allowing programs from doing this because it would be a target for programs to do things like, get the saved password or credit card data out of chrome. Or use save password to login to someone account and buy things in someone elses name.
Second
You could try to spoof user input and input the data exactly like a user would so chrome wont know the difference. But spoofing a user is hard to do and intentionally so because it prevents malicious scripts from taking control of a computer and doing bad things. The makers of windows are accutely aware that spoofing input is a method to circumvent allowed data exchange channels. So the makers of windows made it hard to do. You need to have access to a lot of system assets that most programs wont be given. At a minimum a program has to run as admin on windows to accomplish this, then there are libs that will let you do it. Even then Im willing to bet there are easier way to get the job done. On a machine where you have access to anything and everything it is possible. If you don't have admin access, it should be downright impossible without knowing some unpatched exploit in the system.
Therefore
What you are trying to do goes against what the computer was designed to let you do. If we had more information on what you want to accomplish maybe some of the wonderful people here could help. Getting to the end result you want shouldnt be that hard. But you way of doing it is like trying to run across the ocean, when you just need a boat. As it is my answer is -- dont do it, that's not how windows was designed to work.
I am making a Django application and I am running into an issue. I know Python is interpreted and it would be impossible to completely fight against piracy, however I want to implement some sort of security/licensing feature for my application.
I thought I would post the question because I can't find much information about this online. I'm not sure if I should create some sort of installer which downloads files from a server depending on if a key is valid or not and installs them onto a users host, or if I should encrypt the files upon sending and decrypt them with a key.
If anybody has any pointers or if anybody has faced this before I'd love to hear!
This is very late. but I have implemented license validation through python java bridge. I am generating tokens at the device level. and put a valid key according to that token so that it doesn't work on another device. and I have disabled the main feature for an invalid license key. and also compiled source code in deployment. however, it is not difficult to decompile code but at least we can prevent a normal user.
Here's the deal: I have a Python application for business written in Django. It's not in Cloud, customers should install them at their own servers.
However, Brazil IT laws for tax payment calculation softwares forces me to homologate every piece of code (in this case, every file.py). They generate a MD5 hash and if a customer of mine is running a modified version, I have to pay a fine and should even be sued by Government.
I really don't care if my source code is available to everyone. Really. I just want to guarantee no changes at the source code.
Does anyone have an idea to protect the code? Customers should have root access to servers, so a simple "statement of compliance" should not guarantee anything...
This is not really suited for StackOveflow; but the suggestion I would make is to take the parts of your code that are subject to audit; write them as a Python C module which is then imported. You can ship the compiled module along with your normal, unmodified django application.
This would only work if certain parts of your code are subject to this audit/restriction and not the entire application.
Your only other recourse is to host it yourself and provide your own audit/controls on the source.