Encrypting URL in Objective-C - php

I am using Objective-C to communicate with a PHP script, that works with an API. Although I do not wish for the script to be accessed by anyone else, than the actual iOS App on the users device. As some functions require admin permission, and is essential for the app.
Is there a way I could encrypt the link, so people won't be able to sniff the link? Or somehow limit access of the script.
Regards
Mads

Use https (SSL/TLS) and pin the certificate, that is about as secure as you can get. Even the query string is encrypted. Note that the entire URL including the query string is usually saved in the server log file.
This will require a CA signed certificate and they can be purchased for $50/year if you shop around. There are also several CAs that offer free certificates: Free SSL Certificates from a Free CA

Related

Certificate with Oauth API

I'm not very used to oAuth or using SSL certificates and was just recently forced to look into it for put.io API access. oAuth seems complicated, some methods ever require the end user to fill out their credientials.
So I went to search for a ready made PHP lib that has the full put.io API implemented and noticed he used a method where not even the "application secret" or "client ID" was needed.
All I had to do was feed it my "Oauth Token" value and it connected with ssl vertifypeer and a cafile - StarFieldSecureCertificationAuthority.crt
Now the question I guess is what this certificate really does or proves, and if I can really use his - or if this is something I should generate myself for the target deployment server?
Suprisingly, Google didn't help much at all - and I have still no idea how this oAuth with a certificate works, why it works, and how I can make sure that it does work. Any pointers?
Presumption
I take it this is the "ready made PHP lib" you refer to? If you have a question on what some code does with some file, it's helpful to post a link to the code and even more helpful to post your breakdown of it. If you try to read the code, you'll get better Google terms, and clearer narrower more easily answered SO questions, that have a wider application for other future visitors: A question "What does some code do" is easier to answer and may be found by people in the future that search for the same function.
SSL certificates
It's hard to understand what some API code does with a certificate if we have no understanding of what certificates are for. So lets try to get ssl explained to us. If reading the explaining answer on security.stackexchange.com comes hard to you, youtube is the dyslexics best friend.
So now we know that certificates are used to confirm identity or, in other words, for authentication.
OAuth tokens
OAuth tokens are like car keys; a secret that grants access to a car. In your case the car is put.io (the Resource Server). Some cars have separate keys for starting it, opening the trunk and opening the glove compartment. Some tokens only grant access to some of all the Owners Resources.
Basic idea is here, that we shouldn't leave carkeys left in our care out in the open and we shouldn't stick them in just any car we see. Because it's pretty easy to make a device that looks like a car and reacts like a car, but in fact is a car key copier. Trust me, it's the next big thing after credit card skimming. So we need to confirm the identity of the car, before stick our keys in. We need to authenticate the car.
It's pretty easy to make a device that looks like put.io and reacts like put.io, but in fact is a man-in-the-middle that copies tokens. So we need to authenticate put.io before we send the precious token.
Authenticating put.io
That is where the SSL certificates come in. Without repeating what we learned from the SSL section, we know we should carefully check the authenticity of the server certificate we get from, what we believe is, put.io. We need to check if the signature on that certificate comes from an authority (a CA) we trust. To do that we need the certificate of the CA. Many operating systems and browsers come pre-packed with trusted CA certificates.
Just open https://put.io in your browser and look for the certificate. Often by (right) clicking some padlock icon and some click for more information. You'll see that it is issued by 'Starfield Technologies, Inc.'
Using StarFieldSecureCertificationAuthority.crt
Now in NativeEngine.php we see:
$context = stream_context_create($contextOptions);
The ssl options require either a cafile or a capath. The easiest way for the API maintainer to be cross-platform is supplying a cafile. OS package maintainers will likely patch this and exchange it with the capath to the CA files they supply in their OS.
Can you trust it?
Now if the API maintainer has created that crt himself, he can impersonate any server if you use it. Luckily, you can easily check the fingerprint and see if it corresponds with the one in your browser. You can export the one in your browser if it doesn't.
The OAuth token is what authenticates you against the put.io API. (As you can see in this example, where no additional CA certificate is used.)
The CA certificate and the VerifyPeer setting are there to protect the integrity of the connection between your application and put.io: The library uses it to verify that the server it connected to really is put.io's, before proceeding to submit the OAuth token. Your code should also work if you disable the verification; but then your application would be vulnerable to a MITM attack and an attacker could obtain your OAuth token – and would then have access to your put.io account. (The same technique is used in HTTPS. See this question at ISSE for further details on the verification process.)
Note that your solution works for now, but the put.io API documentation states that they might start to expire OAuth tokens in the future, so in the long term you should switch to a library which is able to obtain new tokens (there's a list in this question):
Although at this time we do not expire OAuth access tokens, you should be prepared for this possibility in the future. Also remember that a user may revoke access via the put.io settings page at any time. Using /authorize will ask the user to re-authenticate their identity and reauthorize your app while giving the user the option to login under a different account.

How do I only allow access to my MySQL database from my iOS app? (Using webapp as gateway to db)

My iOS app needs to connect to a mysql server. To accomplish this, I'd like to create a webapp that acts as the middleman between the client side apps and the server side database.
My concern is that someone can simply figure out the URL that my app uses and pass their own URL parameters - and since the webapp has no idea whether legitimate data is being sent from my iOS app vs. someone just typing in the properly crafted URL from any web browser, the system will be vulnerable.
Let's say I have a PHP function for marking a user as "verified" (after I send them an email verification code). This is pretty standard stuff, but what's stopping someone from making the same request from a web browser?
Of course, the user that the app uses to make database queries will have limited privileges, so the rest of the database won't be at risk. However, even having users activating their accounts from outside the app would be catastrophic.
The option that I thought of was using https so that even if the user figures out the URL, they won't know the password and wouldn't be able to sniff it since it's encrypted from start to finish. Unfortunately, https can be expensive for a poor college student, so I'd like an alternative if one exists.
As stated before, there is no 100 % security possible. But there are several solutions that put together give great security.
Https
As you point out, this is an important part , as it prevents sniffing.
Sessions
Use sessions and don't allow any request without a valid session ( except the first, that must authenticate the app ).
Fingerprint
Check the user agent and set extra http headers, to get a fingerprint unique to your app. ( Still someone could sniff, but he needed to use curl or similar. )
Obfuscate requests
Build your query string and apply a hash function. The server needs to implement the reverse function. ?43adbf764Fz instead of ?a=1&b=2
Encrypt
This goes a step further. Use a shared secret to calculate a hash. On the server repeat the same. This is already strong security. In order to break, one needs to reverse engineer your app.
Use unique shared secret
You say it is a app for iOS. Upon installation a unique token is generated by iOS. Have your app register this token with your server. Like this you have a strong shared secret unique to each installation, and there would be no way to hack your web app.

How to verify that server calls are being made from the app?

I have an android app that needs to connect frequently to the server to retrive or add in the database sensible data. I needed to verify that the calls to the server where being made from the app so I used this approach: how to verify the identity of the client from the server? which consists in a hardcoded string key in the app that's verified in the server.
But then I realized that there were tools like dex2jar, that would reveal all my code (Even with some obfuscation from proguard) in particular this hardcoded key.
Is there any more elegant and safe way to verify that the server calls are being made from my app?
PS: I'm sorry for the English, clearly I'm not a native speaker.
If it's only your client and your server, you can (and should) use mutually-authenticated SSL without purchasing anything. You control the server and the client, so each should only trust one certificate, the one belonging to the other and you don't need CAs for this purpose.
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 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.
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 in my book, Application Security for the Android Platform, published by O'Reilly.
You'll normally store that certificate/private-key in a keystore of sometype (a KeyStore if you're using Android) and that keystore will be encrypted. That encryption is based on a password, so you'll either need to (1) store that password in your client somewhere, or (2) ask the user for the password when they start your client app. What you need to do depends on your usecase. If (2) is acceptable, then you've protected your credential against reverse engineering since it will be encrypted and the password will not be stored anywhere (but the user will need to type it in everytime). If you do (1), then someone will be able to reverse engineer your client, get the password, get the keystore, decrypt the private key and certificate, and create another client that will be able to connect to the server.
There is nothing you can do to prevent this; you can make reverse engineering your code harder (by obfuscation, etc) but you cannot make it impossible. You need to determine what the risk you are trying to mitigate with these approaches is and how much work is worth doing to mitigate it.

Encryption of data between Mac application and PHP application

I am new to the whole encryption world, and I wish to build a Mac application which interacts with a PHP application in order to access and manipulate data remotely.
My problem is that I can't just transfer plain data over the internet, as most of the data being transfered can be very private, as well as username and password are passed for authentication of the user.
I would like to know what kind of encryption/decryption methods I need to use in order the data will be transfered safely over the internet.
Shillo.
The easiest thing to use is SSL with HTTPS. This is well supported by just about any system and HTTP library. No additional encryption is typically necessary.
To do this, you simply need to purchase an SSL certificate and install it on your web server. You can generate one on your own for free, but a certificate authenticated by a 3rd party is often preferred.

Encrypt request from iPhone to web app?

We have the following:
iPhone native app, with login form that posts to:
A php script on remote web server which checks against MySQL user table.
For security, would it be best practice to use some two-way encryption to encrypt every request? including this initial login? otherwise the user and pass will simple be passed to the web app in the clear?
I suppose https would take care of it automatically...
It would be very wise to use SSL or TLS (the protocols that HTTPS uses) to communicate with the server. You could likely get this set up rather easily on a *nix or Windows server using OpenSSL. If you're on a shared host, they likely have an option to purchase an SSL certificate that's valid for a given period of time. This is a fairly trivial process and usually requires about a week (average) with most hosts to get set up.
It should also be noted that while it is never a bad idea to encrypt the login process, it will not make your system more secure "over all" if you have a login from the web that is not secured. For instance, if you secure communication with mobile devices, but not with desktops or laptops, your security may be for nigh. The security of your application is only as strong as its weakest link, so securing your entire application (for all platforms) is very important.
Also, keep in mind that a user's login credentials are only as valuable as the data or resources that they protect: if you encrypt the login information, it is also a good idea to encrypt the rest of the application as well. Wireless sniffing technology could easily steal session data, private user information, or other sensitive data. Securing the entire user session--rather than just the login procedure--is in your users' best interest.
Hope this helps!
Using https is probably the way to go. It's what it was designed for.

Categories