Ho letto l'articolo e non l'ho ancora capito. Quando viene fornita la chiave privata al client?
Dire che ho un client JavaScript - dove conserverei questa chiave privata (una volta assegnata) - un cookie?
Penso che questo possa essere fatto durante l'autenticazione di un utente, se un client JavaScript effettua una richiesta di posta e autentica un utente, il server convalida l'input e restituisce l'id dell'utente (una chiave pubblica) e quindi una stringa generata (memorizzata in una tabella) = la chiave privata?
E poi basta seguire l'approccio (citato) dall'articolo:
[CLIENT] Before making the REST API call, combine a bunch of unique data together (this is typically all the parameters and values you intend on sending, it is the “data” argument in the code snippets on AWS’s site)
[CLIENT] Hash (HMAC-SHA1 or SHA256 preferably) the blob of data data (from Step #1) with your private key assigned to you by the system.
[CLIENT] Send the server the following data:
Some user-identifiable information like an “API Key”, client ID, user ID or something else it can use to identify who you are. This is the public API key, never the private API key. This is a public value that anyone (even evil masterminds can know and you don’t mind). It is just a way for the system to know WHO is sending the request, not if it should trust the sender or not (it will figure that out based on the HMAC).
Send the HMAC (hash) you generated.
Send all the data (parameters and values) you were planning on sending anyway. Probably unencrypted if they are harmless values, like “mode=start&number=4&order=desc” or other operating nonsense. If the values are private, you’ll need to encrypt them.
(OPTIONAL) The only way to protect against “replay attacks” on your API is to include a timestamp of time kind along with the request so the server can decide if this is an “old” request, and deny it. The timestamp must be included into the HMAC generation (effectively stamping a created-on time on the hash) in addition to being checked “within acceptable bounds” on the server.
[SERVER] Receive all the data from the client.
[SERVER] (see OPTIONAL) Compare the current server’s timestamp to the timestamp the client sent. Make sure the difference between the two timestamps it within an acceptable time limit (5-15mins maybe) to hinder replay attacks.
NOTE: Be sure to compare the same timezones and watch out for issues that popup with daylight savings time change-overs.
UPDATE: As correctly pointed out by a few folks, just use UTC time and forget about the DST issues.
[SERVER] Using the user-identifying data sent along with the request (e.g. API Key) look the user up in the DB and load their private key.
[SERVER] Re-combine the same data together that the client did in the same way the client did it. Then hash (generate HMAC) that data blob using the private key you looked up from the DB.
(see OPTIONAL) If you are protecting against replay attacks, include the timestamp from the client in the HMAC re-calculation on the server. Since you already determined this timestamp was within acceptable bounds to be accepted, you have to re-apply it to the hash calculation to make sure it was the same timestamp sent from the client originally, and not a made-up timestamp from a man-in-the-middle attack.
[SERVER] Run that mess of data through the HMAC hash, exactly like you did on the client.
[SERVER] Compare the hash you just got on the server, with the hash the client sent you; if they match, then the client is considered legit, so process the command. Otherwise reject the command!
In secondo luogo, credo che sarebbe più leggibile dall'articolo stesso ...
Sto ottenendo questo giusto?