I shared the encryption and decryption function but I don't think it matters for this question.
Scenario:
https://example.com/posts/awtvwav1689at6awv697atve
is hidden. So we have a query parameter, let's say password
to be able access it.
the id is awtvwav1689at6awv697atve
.
So what I did is when the user hits
https://example.com/posts
An api request is made to the server, then a link to posts id awtvwav1689at6awv697atve
with and encrypted password using the id itself is generated in the server and in sent back to the client.
post.url = `/posts/${post.id}?password=${encodeURIComponent(encryptText(post.id))}`;
then on the frontend, it is used on a anchor tag
<a href={post.url}>Post 1</a>
Then if the user goes to the link
https://example.com/posts/awtvwav1689at6awv697atv?password=<iv:encryptedId>
A request is made again on the server and I decrypt it there then compare it with the original id to see if it still matches.
Is it safe for IV together with encryptedText to be shown in a url (client-side)?
Additional question (you don't need to answer):
If I implement this with AES-GCM, I will have an auth tag.. Is it also okay for it to be in the url? E.g. posts/asdasasdasdas?<IV:EncryptedID:AuthTag>
Thanks!
This might help..
const algorithm = 'aes-256-ctr';
function encryptText(text: string) {
const iv = crypto.randomBytes(IV_LENGTH);
const cipher = crypto.createCipheriv(algorithm, Buffer.from(process.env.ENCRYPTION_SECRET_KEY, 'hex'), iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex');
}
function decryptText(text: string) {
const textParts = text.split(':');
const iv = Buffer.from(textParts.shift(), 'hex');
const encryptedText = Buffer.from(textParts.join(':'), 'hex');
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(process.env.ENCRYPTION_SECRET_KEY, 'hex'), iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}