How to protect API Key in Flex/AIR from decompiling? - api

No obfuscation please and simpler the better.
Similar post is Shared secret with API in an Ajax Adobe AIR app but I was not convinced that these protect from decompiling. If they do, please explain (For example, what's stopping someone from decompiling and using the URLLoader themselves).

If the public key is in your code, there is nothing that can ever stop anyone from decompiling your app and getting the key.
Also - if the key is sent unencrypted from the AIR app to the server, it is a piece of cake monitoring the net traffic and retrieving the key from there. So even if you protect the key by storing it encrypted, you're pretty much screwed.
If you want to protect it, you have to send your calls through a proxy server that you control and keep the key there.

Related

Hide Request/Response header for get request from fiddler or other debug proxy apps

I have mobile app which heavily depends on apis response, I was using charles proxy and fiddler to see the api calls made by my app and I have noticed for one of get api call I am able to see full url with all request parameters(which is fine) and request headers(which include secure keys).
So using those info anyone can execute that api outside of mobile app. my app has millions of user and if someone run script to increase traffic it also increase load on server. so is there any way I can secure or hide those keys ?
I am able to think only one way of doing it is
encryption on both app and api side
is there any better way of doing it ?
You can implement certificate or public-key pinning in your app (for the leaf or the root-CA-certificate). This makes it harder for an attacker to use a proxy and intercept HTTPS traffic. However with XPosed and SSL-Unpinning module this will still work.
Also keep in mind that APK files can be decompiled easily, therefore you don't have to attack the network traffic.
Therefore the next step is to harden your app to make it resistent against manipulation via XPosed or Frida. Note that good harding frameworks cost a lot of money. Usually the protection offered is raising with the cost.
See also this related question.

Authenticating a client to a server

I have a small device that contains a client program which communicates with a server over the internet. Pretty standard stuff.
I have a requirement that the server be able to authenticate messages coming from the device, meaning that all communications from the device be from the authentic client and not from some impostor. It's assumed that an attacker can reverse engineer the client and also load his own programs onto the device.
I'm questioning whether this is even possible. I could certainly load a client certificate into the client, but an attacker could get to this and use it himself. The cost of the device must remain low, so no fancy hardware tricks. Any ideas on how I could do this?
Depending on the device, and what kind of abuse you are talking about, you could use a scheme that needs some kind of activation. Like entering a master key into memory only - so its lost if power is lost - a technic used on some crypto cards.
A way to counter stolen devices could involve some kind of lease of keys that needs renewal on a regular basic by specifying a secret.
A way to counter an imitation/copy could be to works with a common state between the client and server that keeps changing. Like negotiating new encryption keys regularly.
We use a similar thing with our apps and web services. We call it ApiValidation where the client in each request to the service adds a header called ApiID which the server can decode to see if the client is authorized or not.

Rest API encryption with SSL

I'm in the process of designing a REST Api and we're trying to decided how to do encryption. We are currently using https for all request/responses however various logs (dns, browser, ...) will log the plain text url. This raises an issue when we're sending sensitive data in the url, such as "www.mysite.com/user/credit-card-number/". Is there a way to leverage the SSL/TLS public/private keys to encrypt path parameters? For example, "www.mysite.com/user/credit-card-number/" turns into "www.mysite.com/encryptedstring".
I would highly recommend that you not put sensitive data in the URL. If you need something identifying, you could at least use a randomly generated String/UUID/token/whatever that maps to whatever it is that is being identified.
Handling manual encryption/decryption would depend on what language/framework you are using. For example, if you were using Java, then do some google searches on JSSE, which is Java's framework for SSL/TLS.
If you're looking for something to automajically do the encryption/decryption for you, I would think that would also depend on the framework you are using.
If I understand correctly, you are asking if urls are encrypted over an SSL/TLS channel. The answer is yes as this SO question points out. Over TLS, everything is encrypted between the client and server except the IP address and port of the targeted server. (This includes the http headers as well.)
EDIT:
After reading again, I see that you are interested in stopping the the URL being logged. I'm pretty sure the only way to do this is to change the url on the server. Not much help, but my suggestion is don't put the cc number in the url or use some kind of derived key instead.

How secure this signature based authentication for mobile devices is

I am implementing an app where I don't have a system requiring username and password. What I do require is a name and a phone number.
The scenario is like this:
1) user opens the app for the first time
2)app makes a request to my server and gets a unique UserKey
3)from now one any request the app makes to my REST service also has a signature. The signature is actually a SHA(UserKey:the data provided in the request Base64Encoded)
4)The server also performs the same hash to check the signature
Why I don't use SSH:
not willing to pay for the certificate
I don't need to send sensitive data like passwords, so I don't see the benefit of using it
I just need a simple way to call my own WCF REST services from own app
I understand that there is a flow of security at step2 when the UserKey comes in cleartext, but this happens only once when the app is first opened. How dangerous do you think this is?
What would you recommend? Is there any .NET library that could help me?
Actually, there are several problems with that approach. Suppose there's man-in-the-middle whenever you make a request to the server. By analyzing, for example, 100 sent packets he would recognize similar pattern with signature in your requests. Then he would forge his own request and add your signature. The server checks the hash - everything's alright, it's you and your unique user key. But it's not.
There's a notion of asymmetric keys in cryptography which currently is really popular and provides tough security service. Main concept is the following: server generates two keys - public and private; public key is used to encode texts; they can be decoded only with the use of private key, which is kept by the server in secure location. So server gives client the public key to encode his messages. It may be made double: client generates public key and gives it to the server. Then server generates keys and gives encoded with client's public key his own public key. This way it's almost impossible for man-in-the-middle to make an attack.
Better yet, since the problem is really common, you could use OAuth to authorize users on your website. It is secure, widely used (facebook, g+, twitter, you name them) and has implementations already in variety of languages.
Since you control both the application itself and the webservices, you can do this with SSL (which gets rid of the problems with your current approach) without paying for anything. You can create a self-signed certificate and install that on your webserver; configure the SSL context of your client application to only trust that one certificate. Then, create a client-side self-signed certificate and install that within your application. Set the server up to require mutually-authenticated SSL and only allow your self-signed certificate for access.
Done. You client will only talk to your legitimate server (so no one can spoof your server and trick the client in to talking to it) and your server will only talk to your legitimate clients (so no one can steal information, ID, etc). And it's all protected with the strong cryptography used within SSL.

WCF message security without certificate and windows auth

I have a WCF service and client which is going to be deployed to several companies (hundreds). Some companies will run the software in their network and some will run it over the Internet (WCF server at on office, WCF client at another).
We want to encrypt the communication between the WCF server and client. We don't have any need to authenticate the cient / subscriber using WCF security, because we have our own username/password log-in which the clients will use to log on the server.
We can't rely on Windows auth because some of the users will run it over the Internet, and the WCF server may not be on the same domain as the WCF client.
If we use "real" certificates*, companies running the software would have to purchase certificates from a CA and install it, and then configure our software to use it, but this is too complicated for most of them.
We could auto-create certificates during installation of the WCF server, but then we would have to automatically install it into a certificate store and somehow automatically grant IIS permissions to read the certificate. This is more complicated than we would like.
In short, we want a simple solution where the encryption is just based upon a shared secret, in our case the username / password the user is logging on with. I do understand that this won't give the best available encryption, but we're willing to trade some of the security to make the software easier to deploy.
Is this possible?
*With "real" certificates, I mean certificates purchased from a certificate authority, and not one I've created myself / self-signed.
If you want to encrypt the messages on the transport (which is a really good idea!), there has to be some shared knowledge between the sender (the client) and the server. This can be hardcoded, but that's really not a good idea at all - if that "common shared" knowledge is ever compromised, an attacker could decipher and read all your messages.
Also, since it's definitely not recommended practice, there's no support of any kind in WCF to simplify using a shared secret. You're on your own - you have to roll your own 100% of the way.
The only viable way to have a common shared secret exchanged in a safe way is to use a certificate. No way around this, sorry. The certificate doesn't even have to be used for user authentication or anything - but it establishes a shared secret between the caller and the service and thus allows the caller to encrypt the messages in such a way only the intended recipient can actually decrypt and use them.
So I really don't see any way you can get around having certificates on your servers - doesn't need to be on every client, but on every server where your service runs.
Marc
PS: if you really want to investigate the "hardcoded shared secret" approach, you'll need to think about this:
how do you store a shared secret safely on each and every single one of your clients?
how do you use information from that stored shared secret to encrypt your messages?
Typically, the approach would be two-fold:
exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
using that private/public key pair, exchange a common shared secret, e.g. an "encryption key" that will symmetrically encrypt your messages (and since it's symmetrical, the server can use the same key to decrypt the messages)
setup infrastructure on your client (e.g. a WCF extension called a behavior) to inspect the message before it goes out and encrypt it with your shared secret
All in all, it's really not trivial - anything simpler than that is not worth being called "security" at all.
If you look at all that work you will have to do - wouldn't it be easier to just use the WCF built-in certificate mechanisms??
Decent security worth its salt is hard - so why not leverage what's available instead of doing all the work yourself, or worse: come up with a half-baked solution that's so easy to crack you could just as easily send everything in cleartext..... don't under estimate the complexity and amount of code needed to handle even the most basic security scenarios - WCF does this all for you - for free and in a reliable and safe manner - use it! You won't regret it!
Well, with WCF you could use Password credential at message level and SSL at transport level, which I think would be enough in your case.
See here.
For message security, your client provides some credentials and server provides some credentials. For this setup and with your scenario could you not use the client username and password with a Custom Username Validator, and a server certificate to provide the server credentials. This Application Scenario provides a fair chucnk of the configuration setup you would need to achieve this, except the aspNet membership sections, which you would have to replace with your custom validation config.
You would still need valid certificates on your servers (no certificates required on the clients), but I can't see any way around this.
Take a look at the following sample:
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx
It uses certificates but without a certificate store - so no setup is necessary.
Hmm.. maybe something simple could be used. Move the encryption from software to hardware. VPN from each client network to your own and then you can do whatever you like for WCF transport. The line is not clear text and the problem is solved.
Of course this is easier said than done, but most network vendors provide a pretty easy VPN config and it maybe easier than trying to develop an installer for SSL certs and configure the client.
I hope it helps!