I'm writing an iPhone application that needs to send small bits of information (two strings of under 128 characters each, at a time, and this doesn't happen too frequently) to a server when users interact with it. I would like this information to remain confidential, so I'm thinking of some sort of encryption or secure connection would be necessary.
My question is about the server side of things. The server the iPhone app has to communicate with is written in django and is running on lighttpd. What is the most appropriate way (or what is a standard way) of doing this. I was thinking https, which I know on the iPhone I can use ASIHTTPRequest to do a POST request, but I don't know what it requires on the server side. Do I need a certificate? How does the data get encrypted/secured? Are there any django modules to help with this? Do I have to do something to configure lighttpd?
Would something like xml-rpc or json-rpc be simpler? Is it possible to secure such communication? At what level would that occur?
Any help would be much appreciated.
Using xml-rpc or json-rpc are only means to encapsulate your data into a form that is easy to transport. Your iPhone app can transform the Objective C data using one of those formats and your Django server app can transform the data back into Python objects.
Neither of these have anything to do with security.
Creating an HTTPS (SSL) connection encrypts all communication between the client (iPhone) and the server (Django). You will need to get a certificate for the server side. This indicates to the client that the server is who it claims to be. Your next line of research down this path should be about how to configure lighttpd to handle SSL traffic. Once lighttpd negotiates the SSL communication, your Django app will operate as it does for non-secured traffic.
This is your best choice.
If, for whatever reason, you don't want to use SSL, then you could find strong encryption libraries for both ends of the communication. The iPhone app could encrypt the data, send it over an HTTP connection and the Django app could decrypt it. For example, the pycrypto Python library implements strong encryption ciphers such as AES and Blowfish. You might be able to find an implementation of one of these ciphers written in Objective C.
Did you notice that this is getting increasingly complex?
Go with SSL. It's the way security is done for HTTP-based communication.
Hmm it looks like this might be what you're after, have you seen it?
Setting up SSL for Lighttpd/Django
If I read that right, that setup allows your server to answer https and http requests (?)
Then if your whole app isn't going to be https there's this SSL Middleware to help configure some paths as ssl and some not.
If you use https (SSL) on the server side it shouldn't matter if you use XML-RPC or JSON-RPC. All the data you transfer will be encrypted and secure.
I can only speak from our Rails application and nginx. I bought a SSL certificate from GoDaddy (very cheap) and nginx is setup to encrypt the content (Rails is not doing this itself) on the fly when it sends it out. On the iPhone ASIHTTPRequest will be responsible to decrypt the data. All other layers shouldn't be concerned about the encryption, you can send anything you want.
You might also be able to use a self-signed certificate. We decided to use GoDaddy as we also use the SSL certificate for regular browsers, and those show a warning message to the user if they encounter a self-signed certificate, which obviously scares people away.
Related
I am working through some security concepts right now and I was curious if this method has been tried and/or if it is safe taking into consideration "Brute Forcing" is still possible.
Take for example a Microsoft WebAPI Template in Visual Studio where you access a endpoint using a "GET".
The Endpoint would be accessible by any user/application
The String value that a user/application would get from this endpoint would be the password they need, but encrypted using a "KeyValue"
After a TLS Transmission of this Encrypted Value, the user/application would decrypt the String using their "KeyValue"
Is this a secure practice?
Thanks for indulging me and look forward to your responses.
EDIT: Added Further Clarification with Image to Help Illustrate
Suppose the following 2 Scenarios:
Communication between Server and Client
a. Your Server serves the Client application with an encrypted password.
b. The Client can request any password.
c. The passwords are encrypted with a shared Key that is known by both server and client application
As James K Polk already pointed out:
A knowledgable Attacker can and will analyse your deployed application and at some point will find your hardcoded decryption key ("KeyValue"). What prevents him from requesting every password that is stored on the Server?
Rule of thumb here would be: "Do not trust the client side."
Communication between Server and Server
a. You have 2 server applications. Application A is acting as some kind of database server. Application B is your Back-End for a user application of some kind.
b. Application A serves paswords to any requester, not only Server B. With no type of authentication whatsoever.
c. Confidentiality is guaranteed through a shared and hard-coded Key.
I think you are trying to overcomplicate things hoping that no one is able to piece together the puzzle.
Someone with enough time and effort might be able to get information about your server compilation and/or be able to get the Code of Application B. Which again defaults in the scenario of 1. Another point is that there are enough bots out there randomly scanning ips to check responses. Application A might be found and even-though they do not have the shared key might be able to piece together the purpose of Application A and make this server a priority target.
Is this a safe practice?
No. It is never a good idea to give away possibly confidential information for free. Encrypted or not. You wouldn't let people freely download your database would you?
What you should do
All Authentication/Authorization (for example a user login, that's what I expect is your reason to exchange the passwords) should be done on the server side since you're in control of this environment.
Since you didn't tell us what you're actually trying to accomplish I'd recommend you read up on common attack vectors and find out about common ways to mitigate these.
A few suggestions from me:
Communication between 2 End-points -> SSL/TLS
Authorization / Authentication
Open Web Application Security Project and their Top 10 (2017)
I want to encrypt some json from a server and then decrypt it on the iphone/ipad. What are your thoughts on this? What is the best approach to this? Should I scrap this idea and just go via SSL?
Save yourself a lot of trouble and just use HTTPS for all server communications.
As stated above one way is to do everything over https.
An alternative I can think of is the following:
Generate an symmetrical encryption
key per session/login per client on
the server
Send that key to the client over
https
From there on encrypt all the data
you send to the client with that key
The client can then decrypt the
encrypted data
I don't have enough knowledge about https. I often read that is heavy on the resources of the system, but since I have not made or read some good benchmarks I can't give you a rigorous argument for or against it.
The implementation I proposed require a little bit more coding, but you can tailor to your encryption needs.
I think ultimately your decision should be made based on your usage scenario, if you sent very little data, not often to a few client application, you can't go wrong with https. If your expected encrypted traffic is high, the alternative solution might make sense.
We have an iOS app which interacts with various webservices at the backend. The backend however wants to validate that the request coming to it is from our valid iOS app and not from a replay attack or a "man in the middle" attack. We are eventually going to have all our calls changed to https. However, is there any way the backend can validate the request is coming from our legitimate app? We were thinking of using cryptographic nonce with every request, but it would still be prone to "man in the middle" attack. Is there any certificate exchange that can be used between the iOS app and the server?
TLS and SSL support client authentication using certificates. NSStream might support client side authentication, but I have not been able to find a way to do it without dropping down to using OpenSSL for the actual implementation.
Addition:
ASIHTTPRequest supports client certificates since version 1.8, so no fuss in implementing it.
what about using a private/public key scheme so that the iOS app can sign every request it sends?
if private/public key scheme may sound scary, the same idea of "signing" your requests can be easily implemented by hashing your crypto nonce by using sha1, sha2 or other cryptographic hashing algorithms. this would be pretty easy to implement (implementation are readily available), fast, and would ensure a higher security level.
I would suggest to use OAuth. It well known and understood and pretty much secure, and in the case that someone gets your token, you can issue a new one with an app update and revoke the old one.
This is a general http problem, not just an iOS issue. In fact, it's the very problem https is designed to solve, or at least mitigate. You can sign the request, use HMAC to authenticate the message, use digest authentication, and so on, but as long as you're using http, a man-in-the-middle attack cannot be easily detected. Spend your time moving to https as quickly as you can instead.
This problem is impossible to solve absolutely. Anything you put into your scheme can be ultimately broken by jailbreaking the phone and running the client in a debugger. Of course, that doesn't mean you can't make it more difficult to spoof your client using client certificates and whatnot, and you should. But if for example the security of financial transactions depend on your app not being spoofable, that would be bad...
I have an app that connects to an inhouse gameserver. I want to wrap the traffic in SSL to prevent hackers from sniffing the passwords and what not. Anyways, how do I go about doing that with an iphone app? I'm using CFNetwork to communicate to the server, and everything is in our own inhouse protocol instead of using http or something like that.
Thanks
You will need to set the appropriate CFStream properties prior to opening the streams. You do so by first preparing a dictionary using the appropriate kCFStreamSSL* keys and corresponding values and then calling CFWriteStreamSetProperty() to set that dictionary as the kCFStreamPropertySSLSettings property. The property should be shared between both streams in the connection pair.
If your server attempts to negotiate an SSL connection, I believe the streams will cooperate in the negotiation by default. You might have less work to do than you think.
I have an iphone app that retrieves and send data to a server that uses python.
What measures could i take in order to prevent security risks?
I an not handling extremely sensitive data but i wouldn't want people sniffing the contents.
Is using SSL enough to prevent most risks?
Thanks
SSL should be sufficient. It's also a good idea to store the user's password (if you need one to login) inside the Keychain. Btw, don't send anything to the server in a QueryString, always do it with a post, otherwise the SSL won't do much to help you.
If you don't have super-sensitive data, you can also use HMAC messages in order to query your server. I've done this with several projects before.
The message sent to the server may be a little more heavy-weight but is a viable option if you don't want to go with getting a SSL certificate.