Skip to content

Instantly share code, notes, and snippets.

@prashant1k99
Created December 24, 2023 06:58
Show Gist options
  • Select an option

  • Save prashant1k99/eb0da546ec6cb57ea477459e322c30e4 to your computer and use it in GitHub Desktop.

Select an option

Save prashant1k99/eb0da546ec6cb57ea477459e322c30e4 to your computer and use it in GitHub Desktop.

Revisions

  1. prashant1k99 created this gist Dec 24, 2023.
    50 changes: 50 additions & 0 deletions Cryptic.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    const ENCRYPTION_KEY: any = 'your-encryption-key-here' // Must be 256 bits (32 characters) || Please use the above created shared key

    const SharedKey = () => {
    if (ENCRYPTION_KEY instanceof CryptoKey) return ENCRYPTION_KEY
    return window.crypto.subtle.importKey(
    'raw',
    new TextEncoder().encode(ENCRYPTION_KEY),
    'AES-GCM',
    false,
    ['encrypt', 'decrypt']
    )
    }

    async function encrypt(text: string) {
    let iv = window.crypto.getRandomValues(new Uint8Array(16))
    let cipher = await window.crypto.subtle.encrypt(
    {
    name: 'AES-GCM',
    iv: iv,
    },
    await SharedKey(),
    new TextEncoder().encode(text)
    )

    let encrypted = new Uint8Array(cipher)
    return {
    iv: Array.from(iv, (byte) => ('00' + byte.toString(16)).slice(-2)).join(''),
    encryptedData: Array.from(encrypted, (byte) =>
    ('00' + byte.toString(16)).slice(-2)
    ).join(''),
    }
    }

    async function decrypt(iv: string, encryptedData: string) {
    let encryptionMatches = encryptedData.match(/.{1,2}/g)
    let ivMatches = iv.match(/.{1,2}/g)
    if (!encryptionMatches || !ivMatches) {
    throw new Error('Invalid encrypted data or IV')
    }
    let decrypted = await window.crypto.subtle.decrypt(
    {
    name: 'AES-GCM',
    iv: new Uint8Array(ivMatches.map((byte) => parseInt(byte, 16))),
    },
    await SharedKey(),
    new Uint8Array(encryptionMatches.map((byte) => parseInt(byte, 16)))
    )

    return new TextDecoder().decode(decrypted)
    }
    59 changes: 59 additions & 0 deletions KeyGenerator.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    export const generateKeyPairs = async () => {
    const keyPair = await window.crypto.subtle.generateKey(
    {
    name: "ECDH",
    namedCurve: "P-256",
    },
    true,
    ["deriveKey", "deriveBits"]
    );

    const publicKeyJwk = await window.crypto.subtle.exportKey(
    "jwk",
    keyPair.publicKey
    );

    const privateKeyJwk = await window.crypto.subtle.exportKey(
    "jwk",
    keyPair.privateKey
    );

    return { publicKeyJwk, privateKeyJwk };
    };

    export const generateSharedSecretKey = async (publicKeyJwk: JsonWebKey, privateKeyJwk: JsonWebKey) => {
    try {
    const publicKey = await window.crypto.subtle.importKey(
    "jwk",
    publicKeyJwk,
    {
    name: "ECDH",
    namedCurve: "P-256",
    },
    true,
    []
    );

    const privateKey = await window.crypto.subtle.importKey(
    "jwk",
    privateKeyJwk,
    {
    name: "ECDH",
    namedCurve: "P-256",
    },
    true,
    ["deriveKey", "deriveBits"]
    );

    return await window.crypto.subtle.deriveKey(
    { name: "ECDH", public: publicKey },
    privateKey,
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
    );
    } catch (error) {
    console.error("An error occurred while importing the keys:", error);
    throw error; // re-throw the error if you want it to propagate
    }
    };