add encryption/decryption + env vars
This commit is contained in:
parent
2144ae053d
commit
bc2be3302a
5 changed files with 71 additions and 3 deletions
11
.env
11
.env
|
|
@ -1,9 +1,14 @@
|
|||
NODE_ENV=
|
||||
|
||||
# TWILIO
|
||||
TWILIO_ACCOUNT_SID=
|
||||
TWILIO_AUTH_TOKEN=
|
||||
TWILIO_PHONE_NUMBER=
|
||||
TWILIO_ACCOUNT_SID=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||
TWILIO_AUTH_TOKEN=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||
TWILIO_PHONE_NUMBER=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||
|
||||
# SECRETS
|
||||
SECRETS_PASSWORD=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||
SECRETS_SALT=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||
SECRETS_IV_POSITION=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||
|
||||
# PRISMA
|
||||
DATABASE_URL="postgres://hestia:test123@localhost:5432/hestia"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ const ValidateEnvironment = () => {
|
|||
TWILIO_ACCOUNT_SID: z.string().min(1),
|
||||
TWILIO_AUTH_TOKEN: z.string().min(1),
|
||||
TWILIO_PHONE_NUMBER: z.string().regex(PhoneRegex),
|
||||
SECRETS_PASSWORD: z.string().length(32),
|
||||
SECRETS_SALT: z.string().min(16),
|
||||
SECRETS_IV_POSITION: z.number().positive(),
|
||||
})
|
||||
.safeParse(process.env);
|
||||
|
||||
|
|
|
|||
20
src/lib/server/crypto/encryption.test.ts
Normal file
20
src/lib/server/crypto/encryption.test.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { decrypt, encrypt } from './encryption';
|
||||
|
||||
describe('Encryption', () => {
|
||||
it('should encrypt and decrypt data', () => {
|
||||
const data = 'aye its ya boi!';
|
||||
|
||||
vi.mock('$env/static/private', () => ({
|
||||
SECRETS_PASSWORD: 'aac7405eb3384e68c285fc252dbf68b2',
|
||||
SECRETS_SALT: 'c4aeaf8bda72ea45e8c23269ca849013',
|
||||
SECRETS_IV_POSITION: 9,
|
||||
}));
|
||||
|
||||
const encrypted = encrypt(data);
|
||||
console.log(encrypted);
|
||||
const decrypted = decrypt(encrypted);
|
||||
|
||||
expect(decrypted).toEqual(data);
|
||||
});
|
||||
});
|
||||
39
src/lib/server/crypto/encryption.ts
Normal file
39
src/lib/server/crypto/encryption.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { SECRETS_PASSWORD, SECRETS_IV_POSITION, SECRETS_SALT } from '$env/static/private';
|
||||
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'node:crypto';
|
||||
|
||||
const algorithm = 'aes-256-gcm';
|
||||
const password = SECRETS_PASSWORD;
|
||||
const salt = SECRETS_SALT;
|
||||
const iv_position = Number(SECRETS_IV_POSITION);
|
||||
|
||||
function construct(encrypted: string, tag: Buffer, iv: { value: Buffer; position: number }) {
|
||||
return `${encrypted.slice(0, iv.position)}${iv.value.toString('hex')}${encrypted.slice(iv.position)}${tag.toString('hex')}`;
|
||||
}
|
||||
|
||||
function deconstruct(encrypted: string, position: number): [Buffer, string, Buffer] {
|
||||
const iv = encrypted.slice(position, position + 16);
|
||||
const text = `${encrypted.slice(0, position)}${encrypted.slice(position + 16, encrypted.length - 32)}`;
|
||||
const authTag = encrypted.slice(encrypted.length - 32);
|
||||
return [Buffer.from(iv, 'hex'), text, Buffer.from(authTag, 'hex')];
|
||||
}
|
||||
|
||||
export function encrypt(value: string): string {
|
||||
const key = scryptSync(password, salt, 32);
|
||||
const iv = randomBytes(8);
|
||||
|
||||
const cipher = createCipheriv(algorithm, key, iv);
|
||||
const encrypted = cipher.update(value, 'utf-8', 'hex') + cipher.final('hex');
|
||||
const authTag = cipher.getAuthTag();
|
||||
|
||||
return construct(encrypted, authTag, { value: iv, position: iv_position });
|
||||
}
|
||||
|
||||
export function decrypt(value: string): string {
|
||||
const key = scryptSync(password, salt, 32);
|
||||
const [iv, text, authTag] = deconstruct(value, iv_position);
|
||||
|
||||
const decipher = createDecipheriv(algorithm, key, iv);
|
||||
decipher.setAuthTag(authTag);
|
||||
|
||||
return decipher.update(text, 'hex', 'utf-8') + decipher.final('utf-8');
|
||||
}
|
||||
1
src/lib/server/crypto/index.ts
Normal file
1
src/lib/server/crypto/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from './encryption';
|
||||
Loading…
Add table
Reference in a new issue