title: Authenticate and sign HTTP request
body: <p>I'm looking for some guidance/opinion on best practice for both authenticating and signing (integrity checking) an HTTP request.  I'm leaving this fairly open for language and technology used, but the basic parameters and requirements are as follows:</p>
  
  <ul>
  <li>Need both authentication and integrity checking.</li>
  <li>The request contains sensitive data and will be passed over HTTPS, but I cannot assume that the request cannot be sniffed by an attacker, either before it is HTTPS encrypted (at the client end by some illicit piece of installed software) or at the server end, e.g. by a sniffer placed between the HTTPS endpoint and the actual server.  The HTTPS encryption/decryption handling has been passed off to an external load balancer so there is a small window for an attacker to insert a sniffer between the load balancer and the server.</li>
  <li>I need to make sure that a transaction cannot be faked.</li>
  <li>I need to make sure that a transaction cannot be replayed.</li>
  <li>Requests can be GET or POST, and so any extra data needs to stay within the maximum size limit of a GET request.</li>
  </ul>
  
  <p>Things that we have considered:</p>
  
  <ul>
  <li>Username/password on each request. This guarantees authentication I guess, but if an attacker can sniff the username/password pair then it all fails.</li>
  <li>Private key signing of each request. The server will have the public key, only the client will have the private key. This guarantees integrity because only the client could have generated the signature, but the server can check the signature. It generally guarantees authentication as well because the private key is not part of the request data and cannot be sniffed. However by itself it does not stop the transaction being replayed, because 2 transactions with the same data will have the same signature.</li>
  <li>Using a cryptographic client nonce ( <a href="https://en.wikipedia.org/wiki/Cryptographic_nonce" rel="noreferrer">https://en.wikipedia.org/wiki/Cryptographic_nonce</a> ) as part of the request data and including that in the data to be signed. We have had issues with these especially when they are generated on the client side because if they aren't sufficiently random then an attacker can find out how they are generated then the attacker can generate a sequence of nonces of their own, in advance of the client generating the same sequence, which can lead to a denial of service attack because the client will be trying to re-use a nonce that has already been used by the attacker.  Generating nonces on the server side has been considered but it's an extra transaction and potentially a performance issue.</li>
  <li>Including a date/time in the request data, however this can cause issues where the client's clock and the server's clock drift out of sync.</li>
  </ul>
  
  <p>In case some admin decides to flag this as a duplicate, here are other Qs that I have considered that don't quite address the full scope of this issue:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/2585692/what-is-the-current-standard-for-authenticating-http-requests-rest-xml-over-ht">What is the current standard for authenticating Http requests (REST, Xml over Http)?</a></li>
  <li><a href="https://stackoverflow.com/questions/28142813/authenticity-and-integrity-of-http-requests">Authenticity and Integrity of HTTP Requests</a></li>
  </ul>