Combining confidentiality, authenticity and data integrity to form secure URL
There are clients (mobile application), they can share links to their profile info, which should be confidential. The link expires in 5 minutes (configured). They set Auth-Code so that the one who gets the link can access the client's data if he gets the correct Auth code.
The link data should be encrypted.
Every client has a different key
The client can generate the link in offline mode.
I looked at this answer https://security.stackexchange.com/a/63134/238870
But the same secret key is shared between all clients. Given that the profile, in my problem, contains sensitive information, I can't rely on that solution. Also, the solution assumes the clients are online and the server knows the IV (I may be wrong in understanding the answer)
What I came up with is combining asymmetric encryption with digital signature:
Clients will encrypt the link data (Auth code, timestamp, user ID) using the server public key, and signs the data using their private key. The combination of the ciphertext and signature is the link data.
At the server, the encrypted data gets decrypted using the server's private key, then I get the user ID, and by that ID, I get his public key, then verify his signature.
The problem with my solution is that it's costly (asymmetric encryption), and the link gets too long, which is not very handy when sharing links via QR code, which is the main functionality of the application.
If the clients have to be able to generate the links in offline mode, then they must have everything necessary at their disposal - they can't ask a server that might economically keep secrets.
The offline requirement implies asymmetric encryption.
But I would like to challenge this requirement: if the client is offline, how can they post the link to their profile? Also considering that the generated link will expire in five minutes. They would post a link that's already obsolete.
One way of doing it all is through an intermediate storage server:
- the client chooses a random unguessable symmetric password
- the client encrypts the password with the public key of the client, which it has cached
- the client uses the password to fast encrypt whatever it wishes to
- when online, the client sends the server the large blob, and receives back a unique ID as random characters ("Heghlu'meH+QaQ+jajvam"). This can easily become a QR code.
- the server stores the blob and its expiry.
- the other client can download the blob, within 5 minutes, and decrypt it very fast using its own private key to retrieve the symmetric password.