Encrypted query parameters via HMAC I have an unsubscribe link, which needs to be passed a customer id, and a product id, producing a query string something like:

?cid=100&amp;pid=2


I would like to ensure the customer is the one doing the unsubscribing, and that they are unsubscribing from the exact product.  HMAC seems like a logical choice:

?cid=100&amp;pid=2&amp;hmac=&lt;HMAC generated from secret key and cid=100&amp;pid=2&gt;


...and I can validate the HMAC to guarantee authenticity and integrity.

BUT I would also like to keep the customer id and product id confidential if the link is passed around in email, for example.  I can't do that if the HMAC is based off of them.  For example if I just passed the HMAC:

?hmac=&lt;HMAC generated from secret key and cid=100&amp;pid=2&gt;


In this case I cannot not infer the customer id and product id in question (without brute forcing the hash).

Is there a standard way to return encrypted/hashed query parameters?

No, I can't use SSL/TLS.
Not using cryptography on URI:


If you store subscribers on a database, maybe you could also store additional (say) 128-bit random value on some column when there somebody about to unsubscribe. This way there is no meaning for the value beyond this transaction and it cannot e.g. leak anything about the key.


If you cannot use additional data on the database, then use e.g.:


Your favorite AEAD scheme (or Encrypt+HMAC scheme) to encrypt cid+pid pair and to attach authentication tag. Maybe e.g. GCM using 96 bit random IV and 96 bit authentication tag. If there is less than four billion customers and less than four billion product, that would fit in around 256 bits or the same size than (non-truncated) HMAC-SHA256. You may use some variant of base64 to encode the value in URI to 43 characters.


The HTTP standard does not specify how to encrypt or hash parameters. The TLS/SSL is the standard way to apply confidentiality and other security properties.