How to Implement AES-256-GCM Encryption in JavaScript (Web Browser Environment)

I’m working on a project that requires encrypting and decrypting data in the front-end using the AES GCM 256 mode. The back-end team has provided detailed documentation and a Python script for encryption and decryption. Here are the relevant details:

Encryption Steps:

  1. Construct the request as an XML document.
  2. Retrieve a 32-character private access code.
  3. Generate a 12-byte random string as the Initialization Vector (IV).
  4. Create an output buffer with the length of the input request message + 12 + 16. The first twelve bytes represent the IV, and the next sixteen bytes are the authentication tag (AES block size).
  5. Encrypt the data using an AES GCM 256 routine with the access code as the encryption key. Pass in the IV, authentication tag, and data as an array of bytes.
  6. Encode the entire buffer using base64.

Decryption Steps:

  1. Decode the buffer from base64.
  2. Retrieve the 32-character private access code.
  3. Decrypt the data using AES GCM 256 with the access code as the encryption key. Provide the IV, authentication tag, data, and an output buffer for decrypted data.
  4. The decrypted buffer should be an XML document containing the response.

Here’s the Python script provided for reference:

def encrypt(key, plain_text):
    iv = secrets.token_bytes(12)
    cipher = AES.new(key.encode('utf-8'), AES.MODE_GCM, iv)
    ciphertext, auth = cipher.encrypt_and_digest(plain_text.encode("utf-8"))
    return b64encode(iv + auth + ciphertext).decode("ascii")

def decrypt(key, encrypted_text):
    in_buffer = b64decode(encrypted_text)
    iv = in_buffer[0:12]
    auth = in_buffer[12:28]
    cipher = AES.new(key.encode('utf-8'), AES.MODE_GCM, iv)
    dec = cipher.decrypt_and_verify(in_buffer[28:], auth)
    return dec.decode('utf-8')

I’ve attempted to implement this encryption and decryption process in the front-end using various methods and libraries, including the built-in Web Crypto API and the CryptoJS library. However, I’ve encountered issues as CryptoJS doesn’t support GCM mode (reference: GitHub Issue).

Could someone please provide guidance or a code example for achieving encryption and decryption in the front-end using AES GCM 256 mode? Any help would be greatly appreciated.

Thank you!