JavaScript Cryptography using RSA-OAEP

In today’s digital world, secure communication is paramount. This post dives into a JavaScript implementation using the Web Cryptography API RSA-OAEP algorithm to achieve this by:

1. Generating a Key Pair

The generateKeyPair function creates a key pair using the RSA-OAEP algorithm with a 1024-bit modulus and SHA-256 hash. Both the public and private keys are marked as extractable, allowing them to be exported for later use. The function then exports the keys in SPKI (public key) and PKCS8 (private key) formats and returns them.

async function generateKeyPair() {
  const keyPair = await crypto.subtle.generateKey(
    {
      name: "RSA-OAEP",
      modulusLength: 1024,
      publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
      hash: "SHA-256",
    },
    true,
    ["encrypt", "decrypt"],
  );

  const publicKeyJwk = await crypto.subtle.exportKey("spki", keyPair.publicKey);
  const privateKeyJwk = await crypto.subtle.exportKey(
    "pkcs8",
    keyPair.privateKey,
  );
  return { publicKeyJwk, privateKeyJwk };
}

2. Encrypting a Message

The encrypt function takes a public key, a message string:

async function encrypt(publicKeyJwk, message) {
  const importedPublicKey = await crypto.subtle.importKey(
    "spki",
    publicKeyJwk,
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    true,
    ["encrypt"],
  );

  const encrypted = await crypto.subtle.encrypt(
    { name: "RSA-OAEP" },
    importedPublicKey,
    new TextEncoder().encode(message),
  );

  return encrypted;
}

3. Decrypting an Encrypted Message

The decrypt function takes a private key and an encrypted message. Similar to encrypt, it imports the private key and decrypts the message using RSA-OAEP:

async function decrypt(privateKeyJwk, message) {
  const importedPublicKey = await crypto.subtle.importKey(
    "pkcs8",
    privateKeyJwk,
    {
      name: "RSA-OAEP",
      hash: "SHA-256",
    },
    true,
    ["decrypt"],
  );

  const decrypted = await crypto.subtle.decrypt(
    { name: "RSA-OAEP" },
    importedPublicKey,
    message,
  );

  return decrypted;
}

5. Running the Code

The provided code demonstrates the usage by generating a key pair, encrypting a message and descrypting message:

(async () => {
  const { publicKeyJwk, privateKeyJwk } = await generateKeyPair();
  console.log("generateKeyPair: ", publicKeyJwk, privateKeyJwk);

  const encypted = await encrypt(publicKeyJwk, "hello");
  console.log("encypted: ", encypted);

  const decrypted = await decrypt(privateKeyJwk, encypted);
  console.log("decrypted: ", decrypted, new TextDecoder().decode(decrypted));
})();

Important Considerations:

Conclusion

By implementing secure communication techniques like this, you can ensure the confidentiality and integrity of your data, especially when dealing with sensitive information.

Further Reading

Latest blog posts

Explore the world of programming and cybersecurity through our curated collection of blog posts. From cutting-edge coding trends to the latest cyber threats and defense strategies, we've got you covered.