I'm currently writing a program sending data to a server using a private apikey.
I don't want to keep the key in plaintext, but i need it to contact the server.
What kind of reversible encryption could work for this ?
It seems that if you give someone the program and it needs to use the API key, there is no way to avoid giving out the API key. The best you can hope for is to obscure it enough that someone will think it is easier to get the API key elsewhere. Supposing that the API key is so difficult to get elsewhere that someone persists in attempting to decode it from your program, they will eventually get it.
Consider that the end user will be able to snoop on communications with the server, even going man in the middle on an SSL connection, where you are almost certainly sending the key plain-text anyways.
Apply some nuisance crypto, like rot13, and forget about it.
pycrypto has many tools for this. They have many standard types of encryption included in the module.
Here is a quick tutorial.
Related
I am building an application that uses two legged authentication. I got an API key and API Secret, but now I am confused.
I am currently storing my api keys and secrets in a .yml file. But I would like to distribute the .app code, which will end up having the .yml file.
But the .app file will contain the .yml, file, which is bad since everyone will be able to see the API key and Secret.
How can I store the API key and Secret such that my application can access the key and secret without the users seeing it?
The answer depends on a few variables:
Is your source included?
Is it possible to use a server to call the API for you? If so, can you also apply restrictions to the call that the server makes?
Is using compiled code for where you store the key an option? If so, is it possible to obfuscate it?
Here are my suggestions for different scenarios from experience:
The source is not included and using a server is an option, and restrictions can be applied, however using compiled code is not an argument
Then use a server to make requests. Let's say you need to make a call to example.com/api/v1, and you want to call a specific function with a specific set of arguments, then you can only allow requests to that specific API, with that specific set of arguments, and that specific function. This way, it means nothing to a potential attacker since it only calls to one function and nothing else.
The source is not included, using a server is not an option, and compiled code is not an option either
Well, there's not much you can do, obfuscation is your best shot. The best way to do something like this is to hide it deep within your code, and make it obscure, etc., etc., etc.,
The source is included, using a server is not an option, but you can use compiled code
Use really obfuscated assembly and don't share the source for that if you can. For instance, you can have red herring instructions, and just like before, you should hide it deep in your code.
The source is not included, using a server is not an option, but you can use compiled code
For this it's the same as above, since the source for the assembly wouldn't be included
If I didn't list your scenario here, then feel free to comment and I'll edit my answer
While I consider the existing answer technically correct, it may be wroth pointing out that there are some security issues with hardcoding api keys in distributed software.
The nature of an API key is volatile, it is not designed to last forever.
What would happen if the API key is invalidated? Wouldn't that render all distributed software useless then?
And what would happen if the API key has write privileges and is compromised? How could you distinguish between legit and malicious writes?
Even though I understand the overhead, a scenario were the end user can set dedicated keys, obtained by the end user itself, and a way to replace that initial key, would help with above two questions.
One of the API Key features is to be used by a machine that acts on behalf of a user, but if all the users are the same, this feature becomes meaningless.
This question is a bit far fetched (i don't even know if the way i'm going about doing this is correct).
I have a script that gathers some information on a computer. The intent is to have that script ftp/sftp/any-transfer etc some data to a remote server. This script is intended to be distributed among many people also.
Is it possible to hide the password/user of remote server in the script (or perhaps even the implementation details?). I was thinking of encoding it in some way. Any suggestions?
Also, in compiled languages like java or C, is it safe to just distribute around a compiled version of the code?
Thanks.
The answer is no. You can't put the authentication details into the program and make it impossible for users to get those same authentication details. You can try to obfuscate them, but it is not possible to ensure that they cannot be read.
Compiling the code will not even obfuscate them very much.
One approach to the problem would be to implement a REST web interface and supply each distribution of the program with an API key of some sort. Then set up the program to connect to the interface over SSL using its key and put whatever information it needs there. Then you could track which version is connecting from where and limit each distribution of the program to updating a restricted set of resources on the server. Furthermore you could use server heuristics to guess if an api key has leaked and block an account if that occurs.
Another way would be if all of the hosts/users of the program are trusted, then you could set up user accounts on a server node and each script could authenticate with its own username and password or SSH key. Your server node would then have to restrict access based on what each user is allowed to update. Using SSH key based authentication allows you to avoid leaving the passwords around while still allowing authenticated access to your server.
Just set the name to "username" and password to "password", and then when you give it to your friends, provision an account/credential that's only for them, and tell them to change the script and be done with it. That's the best/easiest way to do this.
to add onto jmh's comments and answer another part of your question, it is possible to decompile the java from the .class byte code and get almost exactly what the .java file contains so that won't help you. C is more difficult to piece back together but again, its certainly possible.
I sometimes compress credentials with zlib and compile to pyo file.
It protect from "open in editor and press ctrl+f" and from not-programmers only.
Sometimes I used PGP cryptography.)
What's the best way to protect a symmetric key that needs to be used in code within Google Appengine?
Our application uses Python 2.7
EDIT: we have some database fields that we want protected, that need to be accessed in the code but there is no reason to leave them in the database in plain text. Obviously I'd like to make it as hard as possible to retrieve the key (understanding that it is never impossible).
There is no way to absolutely protect a key if you don't trust the environment that the code is running in. You could store (part of) the key in a trusted location and only accept queries for the key from the domain/IP of your app. But then it would still be in that appengine instance's memory.
The best solution for outgoing messages is to use public-key crypto. Let your code use the public key of the remote party, since those don't have to be kept secret. It can then only be decrypted with the remote's private key.
If you can't trust the appengine's environment, you can't decrypt incoming public-key messages because that would require your secret key to be available to the application.
Edit: Since you've added that you want to protect some database fields, have you thought about hashing them?
what would be a good way to implement an authentication in python? something that already exists is fine too.
I need it for auth over an untrusted network connection. It doesn't need to be advanced, just enough to get a common password over securely.
i have looked at the ssl module. but that module confuses me like there's no tomorow.
long story short: I want ssl or something similar to work. if someone could explain it to me it'd be great.
it's a client-server system. the client can't be trusted, anyone can 'decompile' python. i do need to handle connections from arbitrary clients. as soon as the secure connection is made i can start doing the actual auth using password checksums and whatnot. i'd rather not send plaintext checksums as that'd be pretty darn easy to spoof.
Obviously HTTPS is a good choice, if you do not need encryption, HMAC can provide a secure authentication alternative, and seems to be supported in python.
A client wants to ensure that I cannot read sensitive data from their site, which will still be administered by me. In practice, this means that I'll have database access, but it can't be possible for me to read the contents of certain Model Fields. Is there any way to make the data inaccessible to me, but still decrypted by the server to be browsed by the client?
This is possible with public key encryption. I have done something similar before in PHP but the idea is the same for a Django app:
All data on this website was stored encrypted using a private key held by the system software. The corresponding public key to decrypt the data was held by the client in a text file.
When the client wanted to access their data, they pasted the public key into an authorisation form (holding the key in the session) which unlocked the data.
When done, they deauthorised their session.
This protected the information against authorised access to the web app (so safe against weak username/passwords) and also from leaks at the database level.
This is still not completely secure: if you have root access to the machine you can capture the key as it is uploaded, or inspect the session information. For that the cure could be to run the reading software on the client's machine and access the database through an API.
I realise this is an old question but I thought I'd clarify that it is indeed possible.
No, it's not possible to have data that is both in a form you can't decrypt it, and in a form where you can decrypt it to show it to the client simultaneously. The best you can do is a reversible encryption on the content so at least if your server is compromised their data is safe.
Take a look at Django-fields
You might find Django Encrypted Fields useful.
You and your client could agree on them being obscured. A simple XOR operation or something similar will make the values unreadable in the admin and they can be decoded just in time they are needed in the site.
This way you can safely administer the site without "accidentally" reading something.
Make sure your client understands that it is technically possible for you to get the actual contents but that it would require active effort.
Some other issues to consider are that the web application will then not be able to sort or easily query on the encrypted fields. It would be helpful to know what administrative functions the client wants you to have. Another approach would be to have a separate app / access channel that does not show the critical data but still allows you to perform your admin functions only.