0

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();
    }
KnowYourElements
  • 392
  • 1
  • 12
  • 1
    IV, tag and ciphertext are not secret and can be disclosed. – Topaco Apr 28 '22 at 09:31
  • @Topaco Thanks, if you want you can put it up as an answer – KnowYourElements Apr 28 '22 at 13:16
  • 1
    To be honest the biggest thing you need to consider is why an attacker would bother with decrypting an id if passing the URL they can get the full data. That is, most likely `id` by itself is useless (unless of course you leak some data through your id). They would likely want to steal the data (content) of the post. At which point since going to a iv+encryptedId returns post data, an attacker can just replay an opaque string and still get the data. – zaitsman Apr 29 '22 at 05:24

0 Answers0