In a RESTful API that uses S3-style authentication, the API client signs the request with his secret key using HMAC-SHA1, so the secret key is never transmitted over the wire.
The server then authenticates the client by using that client's secret key to repeat the signature process itself and compare the result to the signature transmitted by the client.
This is all nice and good but it means the server requires access to the plaintext of the client's shared secret. That flies in the face of all the advice out there against storing user passwords in the clear inside your database. Storing only the salted hash of the password is not an option as far as I can tell - because then I can't verify the client's signature.
I should stress that my API is RESTful and thus should be stateless: I'd rather avoid a login step prior to other API calls.
One optional solution is to encrypt all user passwords using some symmetric key algorithm. However, the server would have to store the key to that encryption somewhere easily accessible, e.g. inside the source code. This is better than nothing but not an optimal solution (as @Rook mentioned in his answer, it violates CWE-257).
Another direction for a solution could be something around asymmetric signatures, but I can't figure out how to apply that to the HMAC, and can't find any articles on the subject.
Am I missing something obvious here? Many respectable providers have implemented this kind of authentication scheme - they can't all be violating common security principles, can they?
If not, are there any best practices that you can share?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…