views:

705

answers:

5

I have a password string that must be passed to a method. Everything works fine but I don't feel comfortable storing the password in clear text. Is there a way to obfuscate the string or to truly encrypt it? I'm aware that obfuscation can be reverse engineered, but I think I should at least try to cover up the password a bit. At the very least it wont be visible to a indexing program, or a stray eye giving a quick look at my code.

I am aware of pyobfuscate but I don't want the whole program obfuscated, just one string and possibly the whole line itself where the variable is defined.

Target platform is GNU Linux Generic (If that makes a difference)

A: 

Many password-accepting protocols and facilities have a way to specify a keyfile rather than a password. That strategy will probably work here; rather than hard-coding a password, hard-code a filename (or better yet, make it a parameter!). You could even go as far as SSH and refuse to load keyfiles that aren't (1) owned by the current user (2) only readable by that user.

DDaviesBrackett
I cant use keyfiles in this scenario.
Caedis
+1  A: 

You should avoid storing the password in clear in the first place. That's the only "true" solution.

Now, you can encrypt the password easily with the hash module (md5 and similar modules in python 2.5 and below).

import hashlib
mypass = "yo"
a = hashlib.sha256(mypass).digest()
David Cournapeau
a cool solution, but the password is cleartext because it has to be read into the method that way. I need a way to store the password in a jumbled way that makes no sense to a human without some work, yet have python know exactly what I'm talking about.
Caedis
I'd suggest having a salt. This is a well-known that a *lot* of users are having the same passwords. To protect person with database access from making any correlations, you should to something likesalt = ''.join(random.choice(string.ascii_letters) for _ in range(1,5))hashed_password = 'sha256:%s:%s' % (salt, hmac.new(salt, password, hashlib.sha256).hexdigest())
drdaeman
a hash is one way. I can't decrypt it once it's hashed. I need to send clear text to the method.
Caedis
I suspect the poster needs to use the password to access some other service.
Martin Beckett
@caedis: having to input a clear password in a method is not good design. It is very likely that encoding it will not change much the (poor) security of the software - because you should *never* be able to retrieve the password in text.
David Cournapeau
@David: Requiring a password (or at least some kind of key) is sometimes neccessary. Some of the answers here seem to be taking the assumption that Caedis is on the server side, attempting to authenticate a clients password, but in fact *his program* is the client in the auth process. Sometimes authentication can be performed through a trusted intermediary (eg. authentication from the OS based on the process's user credentials). However, if the only authentication available is that based on a known secret, then the client HAS to know the secret.
Brian
The poster is asking about storing a password to access some tool in his system programatically. You can't encrypt it with a one way hash, because then you can't authenticate against it. Unless I'm confused, you *must* store passwords for such things (example, a MySQL database) in some ultimately decrypt-able way, there's no way around it.
dimo414
+7  A: 

If you just want to prevent casually glancing at a password, you may want to consider encoding/decoding the password to/from base64. It's not secure in the least, but the password won't be casually human/robot readable.

import base64
# Encode password
encoded_pw = base64.b64encode(raw_pw)

# Decode password
decoded_pw = base64.b64decode(encoded_pw)
Johnny G
Thank you! This is exactly what I was looking for.
Caedis
This is a very good answer, you can use the best super strong encryption in your code - but since you must also store the decryption key in the code you really aren't gaining any security. But you might easily fool yourself that you are!
Martin Beckett
This wont protect against a real snoop. But it will protect against an untrained eye glancing at the code and saying "Oh look at that!" and seeing:password = "abc123sdfsdf"
Caedis
I like the shorter spelling password = 'c2VjcmV0'.decode('base64')It will stop working in Python 3.0, though.
Marius Gedminas
A lot of people seem to think there's some way to security with these passwords. There is, as far as I know, no way other than cleartext or simply-transformed-text to store passwords for accessing internal systems. Base64 is about as good an option as you can get.
dimo414
A: 

It depends alot on why you're keeping the password around, and where you feel there is a security issue.

If you're storing or matching this password to a database in the future:

This shouldn't really be a problem, but if you're concerned, use your database's password encryption early and store that ( SELECT PASSWORD('mySamplePassword'); ), then compare the encrypted version directly in your later query.

If you're saving it for later transmision:

There really isn't much you can do. The transmission itself is very likely to be easier to sniff than your handling of the password.

Without knowing a few more details of what you're doing, this is sortof hard to answer.

jkerian
+2  A: 

Obviously your best option is to delegate this to a third party. If you can authenticate with whatever you're connecting to using some other credential (eg. the user account your process is running as), you can leave the permission levels up to the OS layer. Alternatively, if sufficiently important / possible you could prompt the user (storing the key in the (arguably) slightly less hackable wetware instead)

If you do need to store some password or key, I'd recommend you store it seperate from your code, in a file you read in, and de-obfusticate if neccessary. This has the advantages that:

  • You can set the file permissions on the file as tight as possible (ie. only readable by the account your program runs as), unlike the rest of your program which may be read by more people.

  • You won't accidently check it into your version control system!

  • No need to be restricted to printable characters (or use awkward escaping) for a python string, so you can use an arbitrary keyfile if possible, rather than a human readable password. If it's non human-entered, there's no reason to have all the weaknesses of passwords.

To obfusticate, you can use base64 as suggested, or some home-brew scheme like XORing or decrypting with another key stored elsewhere, requiring both locations to be looked at. Be aware that this doesn't protect against anything beyond opportunistic shoulder surfing (if that) - make sure that there is some level of real security as well (including obvious ones like physical access to the machine!)

Brian