How to hide username / password in Python codes?

I have a python code snippet, it uses MySQLdb to connect to the database. The username / password is in the script in clear text. I want to deliver this code to the client, but I do not want them to know the username / password. What is the best way to do this? If the MySQLdb module can also be packaged, it will be even better. Suppose this is on Linux and the client has a standard Python interpreter. This should not be super secure without revealing the username / password in clear text. The client must have permission to write to our database. But the recording operation can only come from our program, we do not want the client to record arbitrarily.

+4
source share
5 answers

Usually password obfuscation is a very bad idea, for reasons that Eric A. Brandstadmoen explains. That is why every DRM solution - DVD-CSS, Blu-ray HDCP, Flash RTMPE, etc. - ultimately fails. On the other hand, sometimes it is necessary for business or legal reasons, and that is why all these DRM solutions were invented in the first place.

You say: "It doesn’t need to be super secure, and not reveal username / password in plain text." And it looks like you have some kind of contractual relationship with your client. It is perfectly reasonable that you do not need to actually stop them from doing this, you just want to force them to exert sufficient effort so that he demonstrates dishonesty on their part or something like that. This, obviously, is what you need to get legal advice otherwise, you are going to spend efforts on creating something that is not enough to give you any legal protection or spend more efforts on creating much more than you you need the legal protection you want, But suppose you have this legal advice, and now you want to continue.


You cannot give someone an encrypted password without providing him with a key. Thus, the strength of encryption is almost irrelevant. It will almost always be easier for them to retrieve the key than to crack the cipher, and it is even easier for them to simply put a breakpoint on the mysqldb login function and capture the decrypted value on the fly. This means that you can use something dirty and cheap. For instance:

def xor(text, key): infkey = itertools.chain.from_iterable(itertools.repeat(key)) return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(text, infkey)) user = 'user' encrypted_passwd = '\x1b\x04\x0a\x18\x12\x16\x19\x01' key = 'key' do_login(user, xor(encrypted_passwd, key)) 

Your lawyer may say that XOR encryption is not a sufficient “best effort” to protect your data, and you should use, say, AES. If so, do it; it really doesn't matter.

Then think about hiding the key and the encrypted password (and possibly the xor function) somewhere in your code: rename them to something harmless, inject them in the middle of other things, don't make it obvious, re is used to create a password, etc. .d.

You can also protect the interface from the MySQL login function. For example, if you complete the decryption code and mysql_connect together in a simple Cython extension, they cannot just break mysqldb.connect or even _mysql.mysql_connect , which means they need a C level debugger instead of a Python level debugger. You can even use C or binary obfuscator around decryption and join code; there are a number of commercial products there, and if your lawyer says that you need to do this, you better use a well-known, modern product, rather than something ordinary.


Meanwhile, if you are looking for technical protection rather than legal protection, you can usually get much more benefit by mitigating the impact rather than trying to avoid it, as dm03514's answer suggests: Limit client access, so even if the user steals client credentials, they can only do the same things that they could do with the client.

For example, let's say you want to prevent users from adding a new delivery record without adding the corresponding billing record with the correct links. You have the logic in the client to verify this, but if they just grab the password from the client, they can add all the delivery records that they want.

Just move this logic to some middleware, so one API call checks and adds both records at the same time. Then give the client access to this middleware instead of directly accessing the database, and anyone who steals the client’s credentials still cannot add invalid delivery records.

This will not stop them from accessing you without a client, but if it is done correctly, it will make it useless for this.

+4
source

import base64

p = 'desired password'

y = base64.b64encode (p)

print y

, and if you want to decode y:

z = base64.b64decode (y)

print z

+4
source

There is everything you can do to avoid this, a couple of which are:

  • Data package with your application, sqlite db file is easy to pack
  • Open your application logic through some kind of API and distribute a client that uses api to communicate with your application, so the client will never have to know any db credentials
  • Create a mysql user account with the correct permissions for your clients.
+3
source

Lines are probably the hardest thing to hide, no matter what you do, to compile the executable with py2exe or confuse it, etc. In practice, you cannot “hide” connection strings from the client. Of course, you could encrypt them, but then you need a means of decrypting them, and the client can easily (relatively) decrypt the username and password yourself.

+2
source

I think it would be better to set up an account for them in the database and control access to the database using database rights.

0
source

Source: https://habr.com/ru/post/1502102/


All Articles