aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/envshare/pkg/encryption.ts
diff options
context:
space:
mode:
Diffstat (limited to 'envshare/pkg/encryption.ts')
-rw-r--r--envshare/pkg/encryption.ts51
1 files changed, 51 insertions, 0 deletions
diff --git a/envshare/pkg/encryption.ts b/envshare/pkg/encryption.ts
new file mode 100644
index 0000000..c9f0e9d
--- /dev/null
+++ b/envshare/pkg/encryption.ts
@@ -0,0 +1,51 @@
+import { fromBase58 } from "../util/base58";
+
+export async function generateKey() {
+ return await crypto.subtle.generateKey(
+ {
+ name: "AES-GCM",
+ length: 128,
+ },
+ true,
+ ["encrypt", "decrypt"],
+ );
+}
+
+export async function encrypt(text: string): Promise<{ encrypted: Uint8Array; iv: Uint8Array; key: Uint8Array }> {
+ const key = await generateKey();
+
+ const iv = crypto.getRandomValues(new Uint8Array(16));
+
+ const encryptedBuffer = await crypto.subtle.encrypt(
+ {
+ name: "AES-GCM",
+ iv,
+ },
+ key,
+ new TextEncoder().encode(text),
+ );
+
+ const exportedKey = await crypto.subtle.exportKey("raw", key);
+ return {
+ encrypted: new Uint8Array(encryptedBuffer),
+ key: new Uint8Array(exportedKey),
+ iv,
+ };
+}
+
+export async function decrypt(encrypted: string, keyData: Uint8Array, iv: string, keyVersion: number): Promise<string> {
+ const algorithm = keyVersion === 1 ? "AES-CBC" : "AES-GCM";
+
+ const key = await crypto.subtle.importKey("raw", keyData, { name: algorithm, length: 128 }, false, ["decrypt"]);
+
+ const decrypted = await crypto.subtle.decrypt(
+ {
+ name: algorithm,
+ iv: fromBase58(iv),
+ },
+ key,
+ fromBase58(encrypted),
+ );
+
+ return new TextDecoder().decode(decrypted);
+}