We are developing REST Web service. We will give Identifier and Secret string to each of our REST clients. When doing requests, clients will authenticate themselves using HMAC algorithm (they will sign body and headers of HTTP requests using Secret string). REST service will receive HTTP headers, body, finds client's secret from database using his Identifier, sign it and looks whether computed signature is equal to the signature provided by the client.

Actually, it's better explained at Amazon S3 authentication documentation page.

In order to use this scheme we have to store clients' Secret keys in plain text, right?

Is there another way to authenticate clients without storing their Secret keys on our servers (or store them in non-recoverable way, for example their MD5-hashes)?

  • Do you actually need to use something like this instead of more standard HTTP-level authentication on top of TLS?
    – ysdx
    Jul 12, 2021 at 10:37

4 Answers 4


Strictly speaking, the use of the term "signature" about HMAC is improper; it is widespread, but still incorrect: signatures are about asymmetric algorithms with a public and a private key, such as RSA.

HMAC uses a secret key (i.e. a bunch of arbitrary bytes) which is used for computing the MAC and for verifying it (it is actually verified by recomputing it). So, in your problem, yes, the server must store either the secret key, or some data which is enough to recover it.

Note that the secret key K can be derived from the password in a non-invertible way. E.g. through a hash function or, better yet, with a Key Derivation Function. The server will store the key K "in plaintext" and knowing key K is enough to produce valid HMAC values. However, this forces an attacker to use some specific software for that, not the standard client which requests a user password. Depending on the context and your attack model, this may or may not be a security improvement.

A way to achieve what you are looking for, but with higher complexity then a plain HMAC, is to use SRP. SRP is an asymmetric key exchange protocol with mutual password-based authentication, with the following characteristics:

  • No need for public key distribution (PKI, certificates...).
  • Client authenticates server and server authenticates client, in the same pass, even in the presence of active attackers ("Man-In-The-Middle" attackers are defeated).
  • No active or passive attackers learns enough information to perform offline dictionary attacks (a dictionary attack is guessing the password by trying random words; the attack is offline if it can be done without interacting with the honest client or server for each guess).
  • What the server stores is not enough to learn the password or impersonate the client (but it allows offline dictionary attacks, which is unavoidable).

The key which results from the SRP protocol can then be used for a MAC algorithm such as HMAC. It needs not be stored: it is just kept in RAM for the duration of the session.

SRP can be integrated in TLS, as explained in RFC 5054. The easiest, most standard supported way to use SRP in your context would be to use HTTPS (i.e. HTTP within a SSL/TLS tunnel) with the TLS part using SRP for key exchange. GnuTLS is an opensource implementation of SSL/TLS which supports SRP.

  • Seems like there are not so many available client/server library implementations (I found mod_gnutls for apache) for SRP. Are there some? Also, do I need to buy SSL certificate, SRP claims it doesn't need trusted third party?
    – galymzhan
    Mar 11, 2011 at 19:26
  • 1
    You never need to buy a certificate; a certificate is "just" a blob signed by a certification authority. What you need is a certificate which will be accepted by the peer, and the peer accepts certificates based on what CA produced them. If you control both client and server, then you can use your own CA, which will cost you nothing (see ejbca.org or openssl.org for details). Also, with SRP, there is no need for any certificate at all, whether bought or not. Mar 14, 2011 at 12:23

SRP does not require a trusted third party or SSL certificate because it uses the existing shared secret between client and server for authentication. A third party is unnecessary when the original two parties already trust each other. And unlike schemes based on HMAC, SRP stores the password on the server in a "non-recoverable" or non-plaintext-equivalent way, which means an attacker who learns the server's secret does not gain the ability to impersonate a client.

Other advantages of TLS-SRP over an ad-hoc HMAC scheme are: resistance to offline dictionary attacks, resistance to replay attacks, and transport encryption.

  • 1
    The only disadvantage of SRP is lack of production-ready client/server implementations distributed as libraries. Am I right?
    – galymzhan
    Mar 13, 2011 at 2:27

As Thomas Pornin pointed out, SRP/TLS is supported in GnuTLS, and OpenSSL will be supporting the SRP ciphersuites in version 1.0.1. Patches are available for OpenSSL 0.9.8 and 1.0.0. If your application is using C/C++, you are fairly well covered.

For Java, there is BouncyCastle, and for Python, there is TLSLite. Which language and platform are you using?

  • 1
    Am I right to assume that you are the Tom Wu who invented SRP? Welcome!! And I guess that the other Tom Wu respondent is you responding first as an unregistered user? Nicely ironic :)
    – nealmcb
    Mar 15, 2011 at 22:22
  • 1
    trevp.net/tls_srp/index.html says that TLSLite implements an older draft of RFC5054 for SRP but doesn't clarify more. What are the differences?
    – nealmcb
    Mar 15, 2011 at 23:22
  • 1
    Right on both counts. As for TLSLite, the only difference should be the calculation of "k", one of the intermediate values. An older draft had it fixed to 3, but RFC5054 makes it a hash of the N and g parameters.
    – Tom Wu
    Mar 16, 2011 at 3:45
  • My REST service is written in PHP (classic LAMP), I found mod_gnutls for Apache, but it stores SRP data in files, not in database, though it isn't big disadvantage. Are there clients for PHP and Flash's actionscript?
    – galymzhan
    Mar 17, 2011 at 8:44

Your solution is using a MAC to authenticate the incoming request. As a consequence, both the client and the server need to have a (per-client) shared secret.

If you don't want the server to have access to the client secret, you could use digital signature instead of a MAC:

  • each client has a private key;
  • the server has the public key of each client but does not need to have the private key in order to verify the signature.

You must log in to answer this question.

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