Skip to content

Web Crypto API implement ECIES like in Javascript

Haikel Fazzani Haikel Fazzani
2024-08-24

To implement ECIES Like (Elliptic Curve Integrated Encryption Scheme) using the Web Crypto API, we can follow a structured approach that involves generating key pairs, deriving a shared secret, and then using that secret for symmetric encryption. Below is a complete example that demonstrates how to do this in JavaScript.

Steps:

Step 1: Create Elliptic Curve Key Pairs

First, we generate an elliptic curve key pair using the generateKey method.

async function generateKeyPair() {
  const keyPair = await crypto.subtle.generateKey(
    {
      name: "ECDH",
      namedCurve: "P-256", // You can also use "P-384" or "P-521"
    },
    true,
    ["deriveKey", "deriveBits"],
  );
  return keyPair;
}

Step 2: Compute Shared Secret and Derive Symmetric Key

Next, we need to derive a symmetric key from the private key and the public key of the recipient.

async function deriveKey(privateKey, publicKey) {
  const sharedSecret = await crypto.subtle.deriveBits(
    {
      name: "ECDH",
      public: publicKey,
    },
    privateKey,
    256, // Length of the derived key in bits
  );

  const aesKey = await crypto.subtle.importKey(
    "raw",
    sharedSecret,
    { name: "AES-GCM" },
    false,
    ["encrypt", "decrypt"],
  );

  return aesKey;
}

Step 3: Encrypt Data with AES-GCM

Now, we can encrypt data using the derived symmetric key.

async function encryptData(aesKey, data) {
  const iv = crypto.getRandomValues(new Uint8Array(12)); // Initialization vector
  const encryptedData = await crypto.subtle.encrypt(
    {
      name: "AES-GCM",
      iv: iv,
    },
    aesKey,
    new TextEncoder().encode(data), // Convert string to Uint8Array
  );

  return { iv, encryptedData };
}

Step 4: Decrypt Data with AES-GCM

To decrypt the data, we can use the same symmetric key and the initialization vector.

async function decryptData(aesKey, iv, encryptedData) {
  const decryptedData = await crypto.subtle.decrypt(
    {
      name: "AES-GCM",
      iv: iv,
    },
    aesKey,
    encryptedData,
  );

  return new TextDecoder().decode(decryptedData); // Convert Uint8Array back to string
}

Step 5: Putting It All Together

Here’s how we can use the above functions to encrypt and decrypt a message:

(async () => {
  const aliceKeyPair = await generateKeyPair();
  const bobKeyPair = await generateKeyPair();

  // Alice derives a symmetric key using her private key and Bob's public key
  const aliceSharedKey = await deriveKey(aliceKeyPair.privateKey, bobKeyPair.publicKey);

  // Bob derives a symmetric key using his private key and Alice's public key
  const bobSharedKey = await deriveKey(bobKeyPair.privateKey, aliceKeyPair.publicKey);

  // Encrypt data using Alice's derived key
  const { iv, encryptedData } = await encryptData(aliceSharedKey, "Hello, ECIES!");

  console.log(encryptedData) // Output: ArrayBuffer
  console.log(String.fromCharCode(...new Uint8Array(encryptedData))) // convert Uint8Array to String

  // Decrypt data using Bob's derived key
  const decryptedMessage = await decryptData(bobSharedKey, iv, encryptedData);
  console.log(decryptedMessage); // Output: Hello, ECIES!
})();

Additional Notes

However, the code lacks a few key components that are part of a complete ECIES standard implementation:

Our code demonstrates the key exchange and encryption/decryption parts of ECIES but doesn’t fully implement the ECIES standard.

Conclusion

This example demonstrates how to use the Web Crypto API to implement ECIES-like functionality by generating elliptic curve key pairs, deriving symmetric keys using ECDH, and encrypting/decrypting data using AES-GCM. While the Web Crypto API does not provide a direct ECIES implementation, this approach effectively combines asymmetric and symmetric encryption techniques to achieve secure data transmission.

Web Crypto API ECIES ECDH AES AES-GCM P-256 curve encryption and decryption in JavaScript Elliptic Curve Integrated Encryption Scheme asymmetric encryption symmetric encryption

More Insights.