I'm generating an access token for users and saving it in the user's browser cookie, i'm wondering if making iv and auth tag public like this is safe or not?
When i create a token i make it like iv.token.authTag
Here's my code for encrypting and decrypting the token
export const encryptAccessToken = (user: User): Result<string> => {
try {
const iv = crypto.randomBytes(8).toString('hex');
const cipher = crypto.createCipheriv('aes-256-gcm', env.CIPHER_SECRET, iv);
const payload = {
created_at: dayjs().format('YYYY-MM-DDTHH:mm:ss'),
expires_at: dayjs().add(1, 'day').format('YYYY-MM-DDTHH:mm:ss'),
user,
};
const cipherStr = cipher.update(JSON.stringify(payload), 'utf-8', 'hex') + cipher.final('hex');
const accessToken = [iv, cipherStr, cipher.getAuthTag().toString('hex')].join('.');
return {
ok: true,
value: accessToken,
};
} catch (error) {
return { ok: false, error };
}
};
export const decryptAccessToken = (accessToken: string): Result<AccessTokenPayload> => {
try {
const [iv, cipher, authTag] = accessToken.split('.');
if (!iv || !cipher || !authTag) {
throw new Error('Invalid access token format');
}
const decipher = crypto.createDecipheriv('aes-256-gcm', env.CIPHER_SECRET, iv);
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
const payloadStr = decipher.update(cipher, 'hex', 'utf-8') + decipher.final('utf-8');
return { ok: true, value: JSON.parse(payloadStr) };
} catch (error) {
return { ok: false, error };
}
};