Generating one time URLs which can be revoked

Looks like you have a pretty good idea what you're doing.

The one-time link pattern is pretty common for things like email verification. Typically, you'd store the expiration date in a database and/or use a signed string in the URL which includes the expiry in the string-to-sign. These are just precautions to avoid trusting user input.

If you want to be really thorough, you can send them the actual random ID or token URL, and then store a hash in the database to avoid someone using the token if you have a data breach.

You're pretty vague about the context of the proposed AES-encrypted parameters. I would usually include sensitive information which is not required for the URL-routing in a message body, instead of the URL. That way, it doesn't appear in web server or proxy logs. AES-encrypted data may also push you over the URL length limit pretty quickly, depending how large the plaintext content is.

Edit: For completeness, Azure Storage SAS Tokens are a great example of a cryptographic method that requires no database record, and is revokable. Revocation is done by changing the service's API Key... which would revoke all tokens issued by the same key.

Given that I don't have a lot of information about the system in use, I would recommend the simpler database lookup, over any solution that requires cryptographically sophisticated measures.

Also, for cryptographic methods to work as a one-time link, some parameter known by the service, and included in the URL, must be changed when the link is used. This parameter doesn't have to be a database lookup, but there does need to be a persisted change. For example, if the link is a one-time upload URL, the presence of a file in the upload directory might invalidate the URL.

Lastly, the database-stored value is simpler in that there is only one source to check for validity. With the no-database solution, you'd need to check against the secret (ie. the encryption key), and also whatever factor invalidates the link after first use.


To use symmetric crypto for an URL parameter would give you one advantage: It eliminates the need to do a database lookup. The downside is that you introduce a secret (the encryption key) that you need to protect and maintain. Since you will need to do the database lookup anyway for checking the revocation status, you don't get any upside. So I would just go for approach #1.

Make sure to use sufficiently long ID:s, and generate them with a CSPRNG. And as nbering says, make sure to hash them (without salt) to protect you in case of a breach.


Software giants like Google use a method of signed URLs

The premise is simple, you send a request with an encrypted string that matches the unencrypted side of the query. Then all you need to do is decrypt it on the server.

For example

example.com?file=file.ext&time={unixtimecode}&{encryptedstringthatmatchesfileandtimestamp}

The use of the encryption key is to ensure that the server/someone with access to the key made the request that a user can follow for a certain amount of time and that the request has not been tampered with. Revoking the string could be as simple as deleting a temporary encryption key meaning that the server wouldn't be able to decrypt the request, even if it was cached.