I am trying to implement SSL pinning and I did, using the didReceiveAuthentication Challenge. I do have a question, however, is that the description of this function
https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455638-webview?language=objc
and so are the URLSession Version of it, both mentioned that only when the challenge is received. My worry is that, would there be website that doesn't ask for client certificate at all? If that is the case, how am I suppose to do SSL pinning then?
Client-side certificate pinning has nothing to do with client certificates. didReceiveAuthenticationChallenge: is called in response to receiving the server's certificate as well. In that case it's called with the protectionSpace.authenticationMethod set to NSURLAuthenticationMethodServerTrust. If the server requests a client certificate, it'll be called again with ...ClientCertificate. If Basic Auth is required, it'll be called again with ...HTTPBasic and so on.
Related
I am using Bearer Token Authentication. when i send in my credentials in the form. I can easily grab my password through Fiddler. I can also see the token along with its claim in fiddler.
I can copy this token and use fiddler to make API calls.
This seems to be a huge loophole in my system. How can i prevent a hacker from not using the token and not seeing the credentials in fiddler.
Is there a way to encrypt the request headers in API calls. Is there a way to encrypt the response headers in API ?
Is it possible to do this without using SSL ?
Please help me understand this
It is possible to do without SSL, but you will have to pretty much replicate most of the SSL, that is trust, key exchange, encryption.
Technically can be done using private/public key as well, but this really complicates the issue as well.
so, use SSL
RFC 6749:
The authorization server MUST require the use of TLS as described in Section 1.6 when sending requests using password authentication.
I am developing an iPhone application for my client in which I have to send requests to a Secure SSL Server(Client's server, everything is ready by server side) with certificate authentication.
I am not getting exact procedure, or exact code showing steps to be followed. (i.e Procedure is not clear to me)
If anybody can explain me the mechanism behind it, it will be helpful for me.
Thank you.
You need not to do anything.
Just use proper URL with https://
All the underlying complexity will be handled by NSURLConnection class. It is as same as calling any other network services.
Using ASIHTTP on the iPhone I am making HTTP requests for things such as sign up and login. They often look something like this:
http://xxxxx.com/signup.php?username=fakeusername&password=fakepassword
From this I usually receive a json response which I then parse.
I would like to soon submit my app to the App Store and need to make this secure. From what I understand this involves encryption and SSL certificates.
I have never done anything like this before and was hoping to get pointed in the right direction. Example code, tutorials, advice, etc. would be greatly appreciated.
So you've got a few questions here:
To do ssl with ASIHTTPRequest, you just need to pass a https url instead of a http one.
you don't need an real SSL certificate, you can disable validation using: [request setValidatesSecureCertificate:NO];
Yes, you're limited by what certificate signing authorities are supported by the iphone. So long as you stick to the big names it shouldn't really be an issue. (And as per 2. you can use a self signed certificate anyway.)
It seems CCATS not necessary anymore, you need an ERN instead - the process has changed, as of Summer 2010! See http://tigelane.blogspot.com/2011/01/apple-itunes-export-restrictions-on.html
for more details go through this
ASIHTTPRequest: https with SSL
I am building a RESTful API in Python with the Pylons framework, serving it with Apache2 and mod_wsgi, and would like to connect it to an iPhone app. I have very little experience with HTTPS, SSL, and certificate authorities, and I am wondering how I would go about securing my API.
How do I make sure that the API is being served through HTTPS? Is it necessary to, as in this example, set up an SSL certificate? If I sign an SSL certificate through an authority not recognized by iOS (CACert.org, for example, and mainly because it is free), will that affect my app's ability to communicate with my server? How have others solved this problem of securing communications between a web-based RESTful API and iPhone apps?
Also, how does OAuth fit into all this?
This really depends on what you mean by "securing" your API.
Do you mean that you want to A) secure it so that unauthorized people are unable to access the API or B) do you mean that you want some level of encryption on the data passed back and forth between the client and server?
If the answer is B or both, then you will definitely need to look at getting an SSL certificate and installing it on the server. Most certificate authorities have guides on how to do this.
I'm not sure what you mean by "an authority not recognized by iOS" but you should still probably consider forking out the dough for a certificate from a recognized authority. It still wouldn't hurt to try CACert.org though if they are offering free certificates. I can't really see there being any problem in terms of the ability of communication between server and client being affected.
In terms of securing your API from unauthorized clients, you could check out OAuth (see http://oauth.net/). There are various Python libraries for OAuth. Check out https://github.com/simplegeo/python-oauth2 for example. The only thing you may want to consider is that there is a reasonable learning curve when it comes to implementing OAuth.
The second link above demonstrates a simple OAuth client and also has example code for a three-legged authentication process.
You can handle certificates programmatically in iOS. You can even use self-signed certificates as long as your code acknowledges the fingerprint. I can't remember the details off the top of my head, but I know you can use didReceiveAuthenticationChallenge to do this.
In the long run, it is simpler to just buy a cert (cacert.org won't do).
I'm building a solution consisting of an app and a server. Server provides some methods (json) and the app uses them. My aim is to make those API methods inaccessible to other clients. What is the best way to do so?
Should I take a look at certificates (to sign every outgoing request)? If yes, where do I start and what is the performance impact of doing so?
What are alternatives?
Put another way, you need a way to distinguish a valid client's request from an invalid client's request. That means the client needs to present credentials that demonstrate the request comes from a valid source.
SSL certificates are an excellent way to assert identity that can be validated. The validity of an SSL certificate can be confirmed if the certificate contains a valid signature created by another certificate known to be secure, a root cert. As noted in other answers an embedded certificate won't do the job because that certificate can be compromised by dissecting the app. Once it is compromised, you can't accept any requests presenting it, locking out all your users.
Instead of one embedded app cert, you need to issue a separate certificate to each valid user. To do that, you need to set up (or outsource to) a Certificate Authority and issue individual, signed certificates to valid clients. Some of these certificate will be compromised by the user -- either because they were hacked, careless or intentionally trying to defraud your service. You'll need to watch for these stolen certificates, place them on a certificate revocation list (CRL) and refuse service to these compromised certificates. Any web server is able to refuse a connection based on a CRL.
This doesn't solve the security issues, it just moves them out of the app. It is still possible for someone to create what appears to be a valid certificate through social engineering or by stealing your root certificate and manufacturing new signed certificates. (These are problems all PKI providers face.)
There will be a performance hit. How much of a hit depends on the number of requests from the app. The iPhone NSURLConnection class provides support for SSL client certificates and client certificates can be installed in the phone from an e-mail or authenticated web request. Managing the infrastructure to support the client certs will require more effort than coding it into the app.
Incidentally, voting down any answer you don't like creates a chilling effect in the community. You're not nearly as likely to get advice -- good or bad -- if you're going to take a whack at everyone's reputation score.
I will now freely admit that it's an interesting question, but I have no idea how it could be done.
Original answer:
Interesting question. Assuming people can't reverse-engineer the iPhone app, the only solution that comes to mind would be to sign requests with a public key, or some other secret known only to the application. By that, I mean adding an extra argument to every API call that is a hash of the destination URL and other arguments combined with a secret known only to your server and application.
To expand upon this: suppose your API call has arguments foo, bar and qux. I would add a signature argument, the value of which could be something as simple as sorting the other arguments by name, concatenating them with their values, adding a secret, and hashing the lot. Then on the server side, I would do the same thing (excepting the signature argument) and check that the hash matches the one we were given in the request.
Consider authenticated HTTP.
For a cheaper alternative, there's shared secret/hash scheme. The client and the server have a shared secret string of text. Upon request, the client hashes together (using MD5, or SHA1, or SHA something else - you choose) the request fields and the secret. The hash value is attached to the request - say, as another POST field.
The server does the same operation with the request and with its copy of the secret, then compares the hash values. If they don't match - service denied.
For added security, you may encrypt the hash with a RSA public key. The client has the public key, the server keeps the private key. The server decrypts the hash with the private key, then the same. I did that with a C++ WinMobile client and a PHP-based service - works like a charm. No experience with crypto on iPhone, though.
UPDATE: now that I think of it, if we assume that the attacker has complete control over the client (ahem jailbroken iPhone and a debugger), the problem, as formulated above, is not solvable in theory. After all, the attacker might use your bits to access the service. Reverse-engineer the executable, find the relevant functions and call them with desired data. Build some global state, if necessary. Alternatively, they can automate your UI, screen scraper style. Such is the sad state of affairs.