75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import BaseService from "@Services/BaseService";
|
|
import { Service } from "typedi";
|
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
|
import crypto from "crypto";
|
|
|
|
@Service()
|
|
export default class CryptoService extends BaseService {
|
|
private key: CryptoKey;
|
|
private jwkKey: any;
|
|
constructor(protected variables: BackendVariables) {
|
|
super();
|
|
this.key = new CryptoKey();
|
|
this.jwkKey = {
|
|
kty: "oct",
|
|
k: variables.KEY_DATA,
|
|
alg: "A256GCM",
|
|
ext: true,
|
|
};
|
|
}
|
|
|
|
private async getKey() {
|
|
if (!this.key) this.key = await crypto.subtle.importKey("jwk", this.jwkKey, {name: "AES-GCM"}, false, ["encrypt", "decrypt"]);
|
|
return this.key;
|
|
}
|
|
|
|
public getTextEncoderDecoder() {
|
|
return { encoder: new TextEncoder(), decoder: new TextDecoder("utf-8") }
|
|
}
|
|
|
|
/**
|
|
* @description : encrypt data
|
|
* @throws {Error} If data cannot be encrypted
|
|
*/
|
|
public async encrypt(data: any) {
|
|
const { encoder, decoder } = this.getTextEncoderDecoder();
|
|
const encodedData = encoder.encode(data);
|
|
const iv = crypto.getRandomValues(new Uint8Array(16));
|
|
const key = await this.getKey();
|
|
const cipherData = await crypto.subtle.encrypt(
|
|
{
|
|
name: "AES-GCM",
|
|
iv,
|
|
},
|
|
key,
|
|
encodedData,
|
|
);
|
|
|
|
const cipherText = decoder.decode(cipherData);
|
|
const ivStringified = decoder.decode(iv);
|
|
|
|
return { cipherText, ivStringified };
|
|
}
|
|
|
|
/**
|
|
* @description : decrypt data with an initialization vector
|
|
* @throws {Error} If data cannot be decrypted
|
|
*/
|
|
public async decrypt(cipherText: string, ivStringified: string): Promise<string> {
|
|
const { encoder, decoder } = this.getTextEncoderDecoder();
|
|
const cipherData = encoder.encode(cipherText);
|
|
const iv = encoder.encode(ivStringified);
|
|
const key = await this.getKey();
|
|
const decryptedData = await crypto.subtle.decrypt(
|
|
{
|
|
name: "AES-GCM",
|
|
iv,
|
|
},
|
|
key,
|
|
cipherData,
|
|
);
|
|
|
|
return decoder.decode(decryptedData);
|
|
}
|
|
}
|