I'm working on an ios application without authentication. Now I would like to protect my server API from calls other then my ios application. A possible solution would be to have the application generate a unique key (based on the appname and the signing), which is not stored on the device since this is the main problem. I could think off an application logic that does some protection combined with some file encryption but the problem is that somewhere something is stored (ex public key can be stored in keychain but still not safe for my API-hackers).
Anyone any tips/advice on how I can handle this ?
thanks in advance
In short, there is no 100% secure way to make sure that the request comes from your application, if the key is available to the iPhone, it's available to extract from the iPhone.
You can make it reasonably safe by calculating a key runtime from info in the application as you say and communicate it over SSL, but a determined attacker can always reverse engineer the key generation too.
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 freely available tools for this, like keytool, and I think (but don't know for sure) that Apple includes a tool for this with the iOS SDK. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource. 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.
Related
TL;DR version: Is there any way to pass a Server certificate to an iOS client that doesn't involve also passing along the Server's private key?
I have written an iOS client app that communicates with my macOS server app (so I have control over both ends). I have implemented certificate pinning using a self-signed certificate to make things more secure. To accomplish this during development, I hardcoded the Server cert into the iOS client app and told the client to only connect to a server that gives you that exact cert during the TLS handshake. Everything is working great.
However in the real world I am selling this system as a set (1 Server, multiple clients to each customer), so I cannot hardcode a Server cert into the iOS client. My plan is to instead deliver the Server cert out of band (via email) to the iOS client like mentioned here: Making Certificates and Keys Available To Your App:
Apps can only access keychain items in their own keychain access groups.
To use digital identities in your own apps, you will need to write code to import them. This typically means reading in a PKCS#12-formatted blob and then importing the contents of the blob into the app's keychain using the function SecPKCS12Import
One way to provision an identity is via email. When you provision a device, send the associated user an email with their client identity attached as a PKCS#12 file.
My problem is that a .p12 file contains the certificate and the private key of the server - this seems very wrong to pass the private key along as well.
Is there any other way to pass the Server certificate to the iOS client that doesn't involve also passing along the Server's private key?
Thanks!!!
I was overthinking things here, the solution is actually pretty simple.
I just needed to email the Server's public certificate out of band to the client device with a custom extension like cert.myCustomExt1234. This is because the .crt extension is already claimed by iOS so you have to register your app to handle custom extensions (see apple docs here). Then in my app I can do all the logic of cert pinning using that out of band delivered Server public cert.
The key was changing the file extension to something not already claimed by iOS.
I want to create a iOS app, and I am starting to design a api using node.js+mongodb+express. I know people can use charles to set up a proxy and when user open the app in the iphone device, they can see the api requests in charles app. So people can use this api to do some harm to the app services or what. I want to secure my api. I won't open my api to others. So, I don't need oauth. What else I can do to secure my api? And if any tutorial is provided, that will be good.
Do it with https, just make sure your app stops working if the certificate is invalid.
Alternative:
Crypt/decrypt your http(s)-body before sending/after receiving with a global password (not recommended) or a public key on your phone and a private key on your application.
If someone gets that pw or public key, they can still manipulate the API.
What you want to do is use https with additional security.
First: In the app "pin" the server certificate, that is validate the server certificate in the app, this is quite common these days. AFNetworking supports this.
Second: Add a certificate to the app and verify it on the server. Now the server knows it is communication with your app.
Now both the server and app have assurance they are communication with authenticated end points.
I want to proxy traffic from an ios application to Fiddler (or Burp). It looks like the application sends a client certificate to the server.
I will need to retrieve this cert from the phone(it's jailbroken) and import it to my proxy. Is there a way to do that ?
The client certificate is used to identify the client. If the programmer of the app made his job well, you will face difficulties (hopefully). Likely, and most secure, the private key and identity resides in the key-chain. Less secure, it resides in a secured archive (.p12, .pkcs12, .pfx) in the bundle, whose password resides in the key-chain.
If the programmer did his job not so well, you might find the password of the secured archive in the clear somewhere in the apps binary (there're actually floating samples around which do exactly this).
I have an iOS client app which connects to a server using HTTPS.
I've added code in the client to verify the identify of the server.
How can a tester testing this feature test that it is now secure, how can they for example create a MITM situation and check that the client rejects connects etc.?
I've tried googling for how to do this but haven't had much luck.
Can it be done using tools like Charles and proxies etc. or is messing around with a wireless router and having detailed knowledge necessary?
This might be over simplification for your solution, but concepts might help.
A web browsers extracts the name of hosts from embedded certificate and do a comparison of host name that we're trying to connect with. If validation fails, we usually see a security warning. For ex: we can connect with facebook by either typing https://www.facebook.com or by typing https://173.252.100.16/. When we choose second option, we get a security warning.
Your program must be using SSL client socket to connect with HTTPS server. The socket must be having capability to extract the hostname from the embedded certificate. Once you get that, compare that with valid HOST NAME that your program is trying to connect with. If it matches, let request proceed, If not, abandon that session.
To re-create MITM, your web server can use a self signed certificate that can be issue to whatever host name you want, but the IP of server could be 127.0.0.1 (for example). Since there is a mismatch between the host name and actual IP, we can probably simulate the MITM situation.
I'm assuming that digital certificate can't be forged in this case.
For an ios 5.0 application connecting to a rest webservice, the customer wants to implement a token based security to ensure that the data being sent over the network is not intercepted and altered in any way... Doesn't https over ssl ensure that the data is not intercepted? and I thought that this would be enough. Pls advise
However, The way the client wants it to work is that starting with the first client authentication request the server would return a token id that would be used to send the next request. In the response for this next request another token id would be sent back that needs to be used for the next request and so on. The problem is of concurrency. Eg when the apns token comes back and the app has to send that to the server and if at that time the iOS application is already making a data request to the server, then the tokens to be used will not match. also since the app has to regularly poll the server for new items, then there are more chances of such concurrency issues to occur.. Any ideas what efficient solutions I can put in the app to counter this?
Or if anyone can suggest better ways of implementing security over the network data, as a possible alternative to the above approach.. solutions that would work for an iOS app and is not battery consuming?
Help in this would be greeeeaaatly appreciated! :-)
Ps. Jfyi Am already doing md5 security on the token being sent
Doesn't https over ssl ensure that the data is not intercepted?
It depends on whom you're trying to protect agains. Plain SSL will protect perfectly fine against anyone between the device and the server.
But it will be trivial for the device owner to create a man-in-the-middle against a client that trusts all CA's on the device. All he needs to do is install his own private CA-certificate on the device, issue a fake certificate for your server signed by this CA, and install this certificate on his proxy/MitM device. To avoid this attack you'd need to do certificate pinning in the App.