My server must receive data from a number of devices who have downloaded my application through an app store or otherwise trusted channel. I need a method to verify that data my server receives is actually from these devices. The server does not have access to a list of these devices ahead of time.
What are some popular ways to accomplish this?
Depends on the platform. The accepted answer to the linked question offers the idea (of using SSL for authentication).
I'd like to add to that answer, that if the client has some API with non-exportable private keys (either hardware-based or encrypted like CryptoAPI certificate storage in Windows), then you can store client certificates there.
Related
When creating any kind of application web,api etc; This days the best practices recommend to secure endpoints by using TLS, but what we can learn from the cloudbleed issue, is that it may not be enough.
Therefore I would like to know what could be done to keep a certain level of security even when TLS is compromised.
For web applications what I currently use is jsencrypt, basically encrypts all data on client browser side before it is sent, but in order to to this I need first to exchange a shared secret (token/cookie) between the server and client, but when dealing with API's that don't support javascript what could be used?
Regarding the exchange of tokens, by instinct it may be obvious to say use OAUTH, OpenID Connect, json tokens , but all of them require or delegate trust to TLS, and again when this is compromised it became useless.
If I am right OpenID could be used without SSL to share a "common secret" by doing Diffie–Hellman key exchange, is there something similar that could be implemented keeping in mind that if TLS gets compromised, easy measure could be taking like revoking tokens or changing "salts" ?
For now I think by following the gpg or rsa (private/public) keys is the way to go, in a way that probably everyone could have access to the public keys but will not be available to see the content of some data signed to a specific user.
But question remains in how to exchange that very first "known secret" between client and server avoiding a possible man in the middle attack considering TLS can't be trusted.
The problem of exchanging the first "known secret" is the same for all protocols, SSL or not. SSL is a public key infrastructure where the basic information that needs to be distributed is the public key of the root certificate of the certificate issuer. The public keys for all ssl certificate issuers are distributed with the browser installation.
Any protocol will depend on some information that is communicated between the server and client in a different channel from the channel where the communication is established. If you don't trust the SSL infrastructure, you will have to send this information by email, postal mail, sms, or by some other means.
However, your problem does not start with the keys neccesary for the encryption libraries you are using in you web application. Your very web application (the javascript files) are also sent from the server to the web browser over SSL. If your SSL communication is compromised by a man-in-the-middle, this man-in-the-middle is also probably able to change the web pages and javascript code that you send to the browser. He could just rewrite your application and remove all encryption code, add new fields and messages for the user, send the user to a different site and so on.
The SSL infrastructure is really a cornerstone in web security, and a neccessity for web applications. Without it, you would have to build a custom protocol for sending encrypted web pages and write a custom browser that would understand this protocol.
With all that said, it is of course possible to add a tiny layer of extra security on top of SSL. You may i.e. create a private/public keypair for each user, send a public key to the user and encrypt all messages from your server to the user with the private key. This could protect against a scenario where a main-in-the-middle is able to listen to the communication but not able to change your messages.
I am looking into ways of securing the channel between my client apps and the server.
I have a rich desktop client (win) and mobile client connecting to a webservice, exchanging data.
Using SSL certificates, server and clients may trust each other. On the secured connection i can exchange username and password and therefore authenticate the user.
However i have certain circumstances where a user must connect to the server via any of the two methods without his credentials but only a literal, like say, a license plate number.
I really want to make sure that in this case i ONLY allow client connects from devices i am sure i know, since there is no further checks on the authentication and a license plate number would be a pretty common literal.
How can i ensure that only "devices" which are known to my server, can interact with my server?
If you want to authenticate the device, you'll need to find a way for the device to prove what it is, without disclosing its secret.
A system similar to a number plate would be quite easy to spoof, for anyone in a position to see that number. Depending on how much control you have on this device, you might not be able to hide it, even if the connection to your server is secured with SSL/TLS.
A potential way to do this would be to use a cryptographic hardware token (or smart card). Some of these tokens can be configured to hold a certificate and private key, with the ability to use the private key without being able to export that private key. The cryptographic operations (signing and decryption) happen on the token itself.
You can use these to perform client-certificate authentication to your server. In this case, you would know that the client has that token. This could work on the condition that you know the CAs were issued its certificates only for key pairs in such tokens: there will be a cost in administering the CA to handle this.
This would at least allow you to tie the authentication to a particular token. Whether you can integrate this with your overall device depends on the kind of device you have.
Please check if TLS Pre-Shared Keys (RFC 4279) can be used for your scenario.
I've setup a Windows Azure database with the data accessible via oData. I'm trying to work out how to secure the connection between a WP7 device and the database. By secure I mean I only want users of the app to be able to access the data from within the app.
I've considered SSL but it's quite expensive for me - is there another way of securing this connection?
Thanks!
There are multiple definitions of "secure". You will need authentication, so Azure only lets the correct users access the data. This is usually handled by a user name and password supplied by the WP7 app.
The WP7 app needs to ensure it is talking to the correct server. SSL handles this using a digital certificate. There are other mechanisms but using something based on a public/private key pair is best because you can validate you are connecting to the correct server without being able to impersonate that server. However, the RSA algorithm used in most cases is computationally expensive.
The data sent between the WP7 app and Azure also needs to be confidential, including the user's password. This is normally handled by encryption. You an choose computationally less expensive algorithm or only encrypt certain data.
The data sent between the WP7 app and Azure also needs some form of tamper detection. Otherwise someone could corrupt the data sent or received. Maybe this is something you can accept for the app but it needs to be a way that an attack cannot easily reproduce. As Shanin's Maxim says, the attacker knows the system.
The problem is that SSL gives you all of these. Yes, it can be expensive but it is one of the best general purpose solutions available. You can change the cipher suites offered by Azure using using Group Policy, code or PowerShell.
If you do not want to use SSL, you need to know what you can sacrifice. In general I would not recommend doing your own encryption mechanism or protocol because us mere humans tend to screw it up.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
securing connection to php server
I'm writing an mobile application to access an online database (I'm more interested in the high-level algorithm/protocol than the platform-specific implementation).
Since keeping the DB updated require a lot of work I want to restrict the access to my sponsored application only (I don't want other apps to take advantage of my DB for free). To do this I need to authenticate the application itself, but how can I do it?
If I store some sort of credentials within the app somebody could try to disassemble the program, retrieve the data and write his own application bypassing mine (even if I encrypt the credentials I still need to store somewhere the decryption key...)
What you want to do is employ mutually-authenticated SSL, so that your server will only accept incoming connections from your app and your app will only communicate with your server.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use the keytool included with the Android SDK (if you're using Android; there are similar tools out there for other platforms) for this purpose. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
If someone/something other than your app attempts to connect to your server, the SSL connection will not be created, as the server will reject incoming SSL connections that do not present the client certificate that you have included in your app.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android, both server and client side. There is also a complete walk-through for Android applications in my book, Application Security for the Android Platform, published by O'Reilly.
Now...you are right in that someone with access to the mobile app could recover the private key associated with the client-side certificate. It would be in a BKS keystore that would be encrypted but your app would need to supply a password to open that keystore. So, someone could reverse engineer your app (fairly easy on the Android platform), grab the password, grab the keystore, and decrypt it to recover the client-side private key. You can mitigate this someway by obfuscating the app to make reversing the keystore password more difficult, or asking the user to log in to the app and using that password to derive the password the the keystore, etc...it really depends on the level of risk you're willing to take on for your application.
What are the best practices for delivering an Adobe Air app that needs a private key in order to communicate with some online API?
Adobe Air apps seem like they are delivered to the user with full source code, so storing any keys within the source would be a really bad idea. I've read some suggestions saying to download the key from your server, but that has the same problem because the url allowing the download would have to be stored in source code. Also, suggestions saying to store in the encrypted local storage don't make sense to me either, because I still have to obtain the private key somehow.
I think this is a global problem of delivering secret keys in any application, since everything can be reverse-engineered (disasamble for executables, IL readers, etc.)
No matter what you do, if the client application needs to somehow "know" a secret key, then the user can know the secret key.
Assuming that:
You deliver a product ("client application") which relys on some 3rd party web service ("the service").
Your company has just one secret key ("company key") for using the service.
The company key must never be exposed (due to possible abuse)
Every piece of information held by or transmitted by the client application is exposed
A solution might be to use some proxy:
The proxy implements the API of the service
The client application connects to the proxy
The proxy connects to the service using the company key
The proxy delegates all calls from the client to the service and vice-versa