title: Protect from replay attacks when using request signatures in secure API communication?
body: <p>I've been reading up on API communication securities and trying to figure out the best way to build a secure API. <strong>I know that OAuth and such exist, but I'm also trying to educate myself in the process and not rely on libraries.</strong></p>
  
  <p>Basically I have a Web Service and in that web service users can register for API. They will be provided a Profile ID and secret key which they have to use to build the API request from another web system.</p>
  
  <p>API request is built similarly to the way banks do it, all input data sent to API has to be sorted, hash calculated and then the hash sent to the server, like this:</p>
  
  <pre><code>// Profile data
  $apiProfile='api123';
  $apiSecret='this-is-a-good-day-to-be-a-secret-key';
  
  // Input
  $input=array();
  $input['name']='Thomas Moore';
  $input['profession']='Baker';
  
  // To ensure that the order of variables checked and received is the same on both ends:
  ksort($input);
  
  // Using serialize() for simplifying things
  // http_build_query() is another option, or just placing values in order
  $input['hash']=sha1(serialize($input).$apiSecret); 
  
  // Making a request to URL:
  // Using file_get_contents() as an example, would use cURL otherwise
  $result=file_get_contents('http://www.example.com/api.php?'.http_build_query($input));
  
  // SERVER CALCULATES COMPARISON HASH BASED ON KNOWN SECRET KEY AND INPUT DATA
  </code></pre>
  
  <p><strong>This is really good and works. But!</strong> My problem is the potential replay attack. If someone snatches this request URL, they can send it to the server again, even though they cannot change the data itself.</p>
  
  <p>Now I've read some things about it that you should also either check the time or add a one-time-use token to the request, but I am unsure how exactly should I do that? Is sending a timestamp with the request really secure enough? (Receiving server would make sure that the request has originated few seconds within the time the request was made, if the clocks are somewhat in sync).</p>
  
  <p>I could also add IP validations to the mix, but these can change and can be spoofed somewhat and are more of a hassle for the user.</p>
  
  <p>I would love this one-time-token type of system, but I am unsure how to do this without exposing token generation to the exact same replay attack problem? (Last thing I need is allowing to give out secure tokens for middle-men).</p>
  
  <p>Opinions and articles would be really welcome, I've been unable to find material that answers my specific concerns. <strong>I want to say that my API is secure</strong>, without it being just marketing speak.</p>
  
  <p>Thank you!</p>