I cant seem to find a reliable asymmetric encryption solution to secure data between a python based server application and a client over an open data channel.
I need some way for my client to prevent a man in the middle attack over an open data channel, my current exchange has me sending my clients a token they use to verify they are talking to my server application by checking the token is valid with a php script on my site.
This is far from ideal and could easily be compromised by waiting to be sent the token and passing it off to another user.
I have tried as3crypto's rsa encryption but it is an old implementation that is not supported by many libraries as well as having a known vulnerability.
I would really like a solution that lets me hard code public/private keys into both the client and server to prevent something like this from happening.
Since decompiling swf content is not a major problem for experienced hackers, I would strongly advise against hardcoding keys. Have you thought about using SSL at all?
Hardcoding they public keys won't help you, if someone really plans an attack, because the SWF itself is transfered over an unsafe channel, thus the keys can be exchanged just as if they were transmitted individually.
There is basically nothing you can do to prevent man in the middle attacks, you can only make them harder. I think HTTPS is about the best you can get and it's also a fairly easy solution.
After doing some research I have decided to code the part of rsa I need from scratch.
I found some python code that will generate raw integer keys of any length and looked up how the rsa algorithm works.
T^P = X (mod R) to encrypt
X^Q = T (mod R) to decrypt
Where T is the starting data, X is the ending data, P is the public half of the key, Q is the private half of the key, and R is the shared part of the key (all integers).
Data will have a nonice whenever possible to prevent replay attacks and the message as a whole will be converted to a long integer to prevent traditional bit by bit cryptanalysis.
Related
I'd like to check the time/date inside an obfuscated python script.
datetime is not reliable as it's easily possible to change the computer clock time.
Using ntplib with a ntp server like europe.pool.ntp.org is not secure either because the user could change the DNS or something like that.
Is there a reliable and secure way to get current date in python ? Using certificates or something like that ? I could gather and parse data from unixtimestamp and verify SSL certificates, but I'm pretty sure that's not the cleanest way of doing this.
It's possible to verify authenticity and integrity of the NTP packets via a shared (symmetric) key. You'd have to ship the key (or retrieve it on the fly from a service under your control) and then use it with one or more NTP servers that support the key. Multiple servers and multiple keys are possible. For example, NIST runs a service that supports this feature.
While packet auth might be enough to mitigate a simple attack vector, the NTP threat model is quite extensive. The hostile actor might not be the client (device) owner...but the date/time you will receive may still be incorrect. Even in the proposed auth solution, the key would have to reside somewhere on the client and a determined attacker could exfiltrate it, even from memory. The mitigation techniques and whether some of the issues cited in the threat model are relevant to you will depend on your definition of "reliable and secure" in your specific use case.
Longer-term solution is NTS, it's adding TLS-/AEAD-based security to NTP.
I am aware that these questions has been asked before several times separately, and most of the answers I've found are "Python is not easy to obfuscate, because that's the nature of the language. If you really need obfuscation, use another tool" and "At some point you need a tradeoff" (see How do I protect Python code and How to keep the OAuth consumer secret safe, and how to react when it's compromised?).
However, I have just made a small Python app which makes use of Twitter's API (and therefore needs OAuth). OAuth requires a Consumer Secret, which is to be kept away from users. The app needs that information, but the user should not be able to access it easily. If that information cannot be protected (and I am using obfuscation and protection as synonyms, because I do not know of any other way), what is the point of having a OAuth API for Python in the first place?
The question(s) then are:
Would it be possible to hardcode the secret in the app and then
obfuscate it in an effective manner?
If not, what would be the best way to use OAuth in Python? I have thought of "shipping" the encrypted consumer secret along with the app and using a hardcoded key to recover it, but the problem remains the same (how to protect the key); having the consumer secret in a server, and have the application retrieve it at start up (if information is sent unencrypted, it would be even easier for a malicious attacker to just use Wireshark and get the consumer secret from the network traffic than decompiling the bytecode, plus how could I make sure that I am sending that secret to my app and not to a malicious attacker? Any form of authentication I know would require having secret information in the app side, the problem remains the same); a mixture of both (have the server send the encryption key, same problems as before). The basic problem is the same: how can you have something secret if critical information cannot be hidden?
I have also seen comments saying that one should use a C/C++ extension for those critical parts, but I do not know anything about that, so if that were the answer, I'd appreciate some extra information.
If you want to deploy on servers (or laptop) you own, you can store secrets in env var or files. If you want to deploy to user, suggestion is that you, or your user should register an API key, generate ssl key, or similar.
You can code your own simple symetric crypt fucntion with a lot of data manipulation to make it harder to reverse.
It is unclear why you'd need to ship your OAuth key with the script. That would mean giving anyone access to your Twitter account, whether or not the key itself is obfuscated inside the app.
The more typical scenario is that you develop some Twitter client, and anyone who wants to run it locally will have to input their own OAuth token before being able to run it. You simply do not hardcode the token and require any user to supply the token.
I Want to create my own safe connection for a VOIP app.
Now I am looking into key exchange which seems to be much more Tricky than encrypting/decrypting.
Are there any better approaches than Diffie-Hellman in practice ?
I understand the concept of Diffie-Hellman but I think it needs the right values to be safe since with natural numbers it could be easily be guessed. How can I get those values using python, what are they and is it really safe from key guessing?
Please help me with some background informations / inspiring.
Diffie-Hellman key exchange, also called exponential key exchange, is a method of digital encryption that uses numbers raised to specific powers to produce decryption keys on the basis of components that are never directly transmitted, making the task of a would-be code breaker mathematically overwhelming.
The most serious limitation of Diffie-Hellman in its basic or "pure" form is the lack of authentication. Communications using Diffie-Hellman all by itself are vulnerable to man in the middle attacks. Ideally, Diffie-Hellman should be used in conjunction with a recognized authentication method such as digital signatures to verify the identities of the users over the public communications medium.
More light on the topic is available below:
1 link 1
2 link 2
3 link 3
DH is fine for this purpose, just make to sure to use 2048 bit keys or more.
However for VoIP the standards are TLS with SRTP/zrtp so it would be better if you would implement these. With DH you loose compatibility and will introduce a lot of complications. Also note that DH is only for key exchange, so you will need something also for the encryption itself. With TLS you could handle all these in one step by using a well know implementation instead to write your own encryption stack from scratch.
Diffie-Hellman is a key exchange algorithm. So Anyone can access your public parameters. You can use safety except declassified private parameters. It's so important create sharedkey safety. If you want to more secure system, try forward-secrecy
I have a server implementing a python API. I am calling functions from a frontend that uses Angular.js. Is there any way to add an authentication key to my calls so that random people cannot see the key through the Angular exposed code? Maybe file structure? I am not really sure.
As long as you send the sensitive data outside, you are at risk. You can obfuscate your code so that first grade malicious users have a hard time finding the key, but basically breaking your security is just a matter of time as an attacker will have all the elements to analyse your protocol and exchanged data and design a malicious software that will mimic your original client.
One possible (although not unbreakable) solution would be to authenticate the users themselves so that you keep a little control over who is accessing the data and revoke infected accounts.
I'm looking at using a crypto lib such as pycrypto for encrypting/decrypting fields in my python webapp db. But encryption algorithms require a key. If I have an unencrypted key in my source it seems silly to attempt encryption of db fields as on my server if someone has access to the db files they will also have access to my python sourcecode.
Is there a best-practice method of securing the key used? Or an alternative method of encrypting the db fields (at application not db level)?
UPDATE: the fields I am trying to secure are oauth tokens.
UPDATE: I guess there is no common way to avoid this. I think I'll need to encrypt the fields anyway as it's likely the db files will get backed up and moved around so at least I'll reduce the issue to a single vulnerable location - viewing my source code.
UPDATE: The oauth tokens need to be used for api calls while the user is offline, therefore using their password as a key is not suitable in this case.
If you are encrypting fields that you only need to verify (not recall), then simple hash with SHA or one-way encrypt with DES, or IDEA using a salt to prevent a rainbow table to actually reveal them. This is useful for passwords or other access secrets.
Python and webapps makes me think of GAE, so you may want something that is not doing an encrypt/decrypt on every DB transaction since these are already un-cheap on GAE.
Best practice for an encrypted databased is to encrypt the fields with the users own secret, but to include an asymmetric backdoor that encrypts the users secret key so you (and not anyone who has access to the DB source files, or the tables) can unencrypt the users key with your secret key, should recovery or something else necessitate.
In that case, the user (or you or trusted delegate) can retireve and unencrypt their own information only. You may want to be more stringent in validating user secrets if you are thinking you need to secure their fields by encryption.
In this regards, a passphrase (as opposed to a password) of some secret words such "in the jungle the mighty Jungle" is a good practice to encourage.
EDIT: Just saw your update. The best way to store OAuth is to give them a short lifespan, only request resources your need and re-request them over getting long tokens. It's better to design around getting authenticated, getting your access and getting out, than leaving the key under the backdoor for 10 years.
Since, if you need to recall OAuth when the user comes online, you can do as above and encrypt with a user specfic secret. You could also keygen from an encrypted counter (encrypted with the user secret) so the actual encryption key changes at each transaction, and the counter is stored in plaintext. But check specific crypto algo discussion of this mode before using. Some algorithms may not play nice with this.
Symmetric encryption is indeed useless, as you have noticed; however for certain fields, using asymmetric encryption or a trapdoor function may be usable:
if the web application does not need to read back the data, then use asymmetric encryption. This is useful e.g. for credit card data: your application would encrypt the data with the public key of the order processing system, which is on a separate machine that is not publically accessible.
if all you need is equality comparison, use a trapdoor function, such as a message digest, ideally with a salt value. This is good for passwords that should be unrecoverable on the server.
Before you can determine what crypto approach is the best, you have to think about what you are trying to protect and how much effort an attacker will be ready to put into getting the key/information from your system.
What is the attack scenario that you are trying to remedy by using crypto? A stolen database file?