3

I'm designing an API intended for use by a very limited number of trusted clients, likely a server cluster. The API can be accessed only through HTTPS. To authenticate the clients, I'm considering 3 methods:

  • TLS client certificate. The certificate might be issued internally as both server and client are operated by the same organization.
  • HMAC-SHA1 over some data items: requested URL, date time,... for each request. The MAC will be put in HTTP Header. In other words, a simpler version of Amazon S3's REST authentication.
  • HTTP Basic authentication with pre-shared username & password.

To my understanding:

  • TLS certificate is the "most secured" of the three, while HTTP basic authentication is the "least secured". "Most secured" is in the sense that the method provides protection against all attacks also protected by others, and some more.
  • HMAC-SHA1 is vulnerable to replay attack, however since the communication will be secured by TLS anyway, there should be no problem.
  • HTTP basic authentication puts shared secret on the wire all the time (though still protected with TLS), so I have some (possibly unfounded) worries about it.

Are my points correct? Is there any other security issues I should be aware of?

  • 1
    Please remove your question on SO 1) to prevent migration still or 2) to prevent cross-site duplicates. And then you can remove your first paragraph. – Jan Doggen Nov 4 '16 at 11:02
  • 1
    Client certs would be better IMO as they can not only protect against unauthorized usage of the API but can prevent mere access - the web server wouldn't even complete the TLS handshake without a valid cert, shielding your API from all the bots and the background noise of the internet. – André Borie Nov 8 '16 at 11:57
2

I think you summed it up well.

A few additional points beyond the technical security of these solutions:

  • TLS certificates require management, they expire, etc. You should consider whether you have the resources (can automate to some extent) certificate management. A pretty bad scenario is when IT operations just gets fed up with all the issues and disables cert validation because that way it just works. ;)

  • An HMAC-SHA1 signature implementation is also reasonably good and you can limit the time window of a replay (and as you said, in TLS it's ok). However, the implementation is more complex than the other too. If it's a larger team that will maintain the code and especially if you have to change the implementation sometimes, there is a good chance that a flaw will be introduced. The other two are much simpler in terms of source code that needs to be written.

  • HTTP Basic is very simple and may be ok with TLS, but as you said, that I would say is the least secure of the three. Many people still think it's good enough for many purposes though, it depends on what you want to protect against. TLS is considered secure against MitM attackers. I think the biggest advantage is simplicity, there is not a lot to go astray.

2

It's a no-brainer to me: TLS client-side certificates. They are the fastest, most secure, least homebrew and you say you are already using TLS libraries. They are also quite simpler than HMAC option in terms of implementation.

Don't do public key infrastructure (PKI) stuff: simply let client-side generate a self-signed cert valid for 100 years and marked as not being a CA. Trust that cert on the server. There is no reason to make PKI, YAGNI... It doesn't solve your problem, it introduces CRL or OCSP issues, SHA1 class of issues and many other side-effects. Think about a self-signed certificate as simply an RSA public key - it is one in fact.

Ensure both client and server do cache TLS sessions. This will give you blazing fast TLS connections. (You benefit this when having only server-side certs. You benefit twice when you add client-side certs.)

There is very little programming with this, this just needs implementing simple textual configuration options that pass some text (like a location of a truststore file to use). Admin staff does the rest. They are also able to test stuff themselves with openssl s_client etc.

Any future vulnerabilities can be handled administratively (for example via openssl ugprade or JDK upgrade).

The HMAC solution is a black box for admins. Any problems need to be solved by programmers.

With HTTP basic auth, you're doing a strange job. You still need to implement TLS and set up X509 certificates (for example client will most likely trust something other than the default public CAs) and you still need to manage it and upgrade it. But you do half job and for the other half you use a completely different mechanism. It does look valid, but it has a little bit of bad smell.

  • I totally forgot about having to implement TLS since it would use pre-existing system. It's true that TLS client certificate would be more coherent from ground up. – Nevill Nov 30 '16 at 11:04
1

I believe your assumptions are correct as long as you have a strict policy that the client terminates the connection in case the trust chain of the server certificate cannot be verified or in case any other TLS security concern pops up. If you trust the TLS then you are safe against replay etc.

You could, however, spend a couple of thoughts on the question how quickly you can react if your authentication information is compromised. Here, switching to a shared key might be significantly easier or harder as compared to putting a client certificate on a CRL, this completely depends on your environment. Whereas TLS provides good protection for data transmission over the wire the options you describe might provide different level of comfortability/reliability/security when it comes to revoke the authentication information.

  • Good point regarding certificate revocation. At first I thought it should be as easy as with secret key, but it turned out it can be a lot more complicated in our system. – Nevill Nov 23 '16 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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