1

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!

2
  • 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, 2012 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. May 1, 2012 at 20:07

5 Answers 5

2

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.
1
  • 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 :-) May 1, 2012 at 20:16
2

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

1
  • 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. May 1, 2012 at 20:18
2

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.

1
  • 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). May 1, 2012 at 20:10
0

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.

1
  • Thanks. I think I have a clear understanding of the options now. May 2, 2012 at 12:24
0

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

1
  • 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, 2012 at 2:59

Not the answer you're looking for? Browse other questions tagged .