Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have the challenge of implementing an API to be consumed by relatively non-technical clients -- pasting some sample code into their WordPress or homegrown PHP site is probably as much as we can ask. Asking them to install SSL on their servers ain't happening. So I am seeking a simple yet secure way to authenticate API clients.

OAuth is the obvious solution, but I don't think it passes the "simple" test.

Adding a client id and hashed secret as a parameter to the requests is closer -- it's not hard to do md5($secret . $client_id) or whatever the php would be.

It seems to me that if client requests could use the same approach as SSH public keys (client gives us a key from their server(s) there should be some existing magic to make all of the subsequent transactions transparently work just as regular HTTP API requests.

I am still working this out (obviously :-), so if I am being an idiot, it would be nice to know why.

Thanks!

share|improve this question

closed as off topic by Zoredache, Magellan, Scott Pack, SvW, rnxrx Oct 28 '12 at 1:58

Questions on Server Fault are expected to relate to professional server, networking, or related infrastructure administration within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here.If this question can be reworded to fit the rules in the help center, please edit the question.

    
It seems to be that you are trying to invent some Frankenstein security system. That really is a bad idea, when it comes to security systems you should always prefer well known, well tested solutions. When trying to build your own thing, the chance that you will mess something up is pretty large. See Schneier's law. –  Zoredache May 1 '12 at 16:45
    
Actually, I am trying to avoid exactly that! I know a number of methods of authentication, and as an experienced developer I know that most are harder than the people we expect for clients will be able to easily implement. So I am just looking for alternatives that might be simpler, and suitably secure. –  Tom Harrison Jr May 1 '12 at 20:07
add comment

5 Answers

up vote 2 down vote accepted

If you are hosting the service, then you could setup SSL on your side. There are several options to authenticate the clients.

  1. You can use a token like you said in the question.
  2. You can use http auth, and have them specify username and password.
  3. You can use client SSL certs like Mircea said.
  4. You can base it off of the connecting ip address.
share|improve this answer
    
I guess the token is effectively the same as public key, but as I think about it, I am conflating SSL (which they don't need to do anything special to use) and authentication. So as long as we force SSL, passing a token/key is probably sufficiently simple :-) –  Tom Harrison Jr May 1 '12 at 20:16
add comment

Something similar to SSH public keys is SSL client certificate authentication aka 2 way SSL.

share|improve this answer
    
Thanks for the lead. I looked into this and think it still requires something fancier than ssh-keygen, which is probably more than many clients could even pull off, given shared hosting and the like. –  Tom Harrison Jr May 1 '12 at 20:18
add comment

Its rather a large topic, is your API purely web based? Why is SSL too hard? If you want trusted communications from automated clients and to guaruntee non-repudiation, youre going to need SSL. If your API is accessed from a user session, can you implement 2 factor authentication. Using something like the RSA tokens, or even the google authenticator if they have smartphones.

share|improve this answer
    
SSL's no problem for our side, but the clients are super low-tech folks, and because we're dealing with money, we need something secure , mainly for the data transmission, and to a lesser degree for authentication (for which a shared secret will do). –  Tom Harrison Jr May 1 '12 at 20:10
add comment

In the simplest way, you could enable HTTP Basic authentication on your side. Provided that you've enabled HTTPS on your server, and made sure the clients were configured with the https:// URIs (avoid relying on automatic redirects, especially with HTTP Basic in fact). Just give each registered client a username and a password.

Most clients should support this form of authentication. If your client is a PHP server, setting the CURLOPT_USERPWD parameters should do.

It's also quite common to use an API key (based on some UUID, for example) as a query parameter for some APIs. How convenient this is may depend on your side of the code. Overall, it's quite equivalent to Basic username/password in terms of security (except that you may have to map the key to a username).

If you want to use public key authentication, use SSL/TLS client certificates. This is more involved. You may have to create your own CA for this (this can be done in such a way that the key generation is done in the user's browser, but this can still be inconvenient).1

The downside is that the users may have to convert certificates from one format to another for them to be used.

Either way, if SSL is used on your side and you expect them to paste some PHP/Curl code, they may still have to do a bit of configuration. At least, CURLOPT_SSL_VERIFYPEER should be TRUE, CURLOPT_SSL_VERIFYHOST should be 2 (default) and CURLOPT_CAPATH should point to a directory containing their trusted CA certificates. Where this is may depend on their host.

1 It's also possible to turn an SSH RSA key into a self-signed X.509 certificate, but that's quite technical (and would also require some work on your side). Other public key authentication mechanisms (possibly based on SSH keys) on top of HTTP would be up to you to create, which is generally a bad idea (hard to get right on your own). It's certainly not worth the effort, since HTTPS with client authentication would provide you with something proven, and already supported by existing libraries.

share|improve this answer
    
Thanks. I think I have a clear understanding of the options now. –  Tom Harrison Jr May 2 '12 at 12:24
add comment

I think what you can do is use Diffie Hellman to create a shared secret based on public/private key pairs. I have used a similar approach; I think if you are trying to control authorization to your API from multiple sources, this approach can work well.

Please see this http://p4r1tyb1t.com/?p=723

share|improve this answer
    
Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. –  Scott Pack Oct 21 '12 at 2:59
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.