0

I'm attempting to migrate from Browser-only window.subtle.crypto to CryptoJS so it is universally available across all platforms using Expo.

Essentially: window.subtle.encrypt({name: AES-GCM}) -> CryptoJS.AES.decrypt

For the existing data encrypted, CryptoJS should be able to decrypt it utilizing the AES generated key from window.subtle.generateKey, so the method for window.subtle.encrypt cannot be changed and it's being done as described below

I want to decrypt the window.subtle.encrypt encrypted at CryptoJS's CryptoJS.AES.decrypt

so for this, I've written this test code:

const text = "This is an encrypted message";

const generateKey = async () => {
    const key = await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 128 }, true, ["encrypt", "decrypt"]);
    const key_exported = await window.crypto.subtle.exportKey("jwk", key);
    return key_exported.k;
}

const printCurrent = async () => {
        let kkey = await generateKey();
        await window.crypto.subtle.importKey(
            "jwk",
            {
                k: kkey,
                alg: "A128GCM",
                ext: true,
                key_ops: ["encrypt", "decrypt"],
                kty: "oct",
            },
            { name: "AES-GCM", length: 128 },
            false,
            ["encrypt", "decrypt"]
        ).then(function(key){
            window.crypto.subtle.encrypt({ name: "AES-GCM", iv: new Uint8Array(12) }, key, new TextEncoder().encode(JSON.stringify(text))).then( function(encryptedObject){
            const cryptojs = CryptoJS.AES.decrypt(encryptedObject,key,{iv: new Uint8Array(12));
            console.log("cryptojs: ", cryptojs.toString(CryptoJS.enc.Utf8));
            });
        } );
    }
    printCurrent();

I've seen that CryptoJS accepts only WordArray, and the output of the encrypted object ['encryptedObject'] from subtle crypto is ArrayBuffer [46 size], I've tried converting ArrayBuffer to WordArray via CryptoJS.lib.WordArray.create(encryptedObject) but still no luck.

Any help or guidance is appreciated, thanks so much!

  • 1
    The code has many conversion bugs concerning the different array types (`ArrayBuffer`/`TypedArray`/`WordArray`) and Base64 variants (Base64/Base64url), which could be fixed. However, a showstopper is that CryptoJS does not support GCM, s. [Block Modes](https://cryptojs.gitbook.io/docs/#block-modes-and-padding). – Topaco Dec 01 '21 at 11:00
  • yeah I'm quite puzzled about the conversions for even the key or the cipher/thing to be decrypted in itself. I could attempt fixing them further if you can give leads however by saying showstopper, you're saying it's not possible? I'm trying to search compatible libraries for Expo that supports Native Android, iOS, and Web, so far attempted running react-native-aes-gcm-crypto but no luck, it's just not importing properly in Expo but that might be another story. Any further input is greatly appreciated, thanks so much for your time! – junaiddarajat Dec 01 '21 at 12:23
  • 1
    Decryption with CryptoJS is **not** possible because CryptoJS does not support GCM. Either you apply another JavaScript crypto library that supports GCM, or you use a mode that CryptoJS supports when encrypting. [Here](https://gist.github.com/jo/8619441) is a list of crypto libraries for JavaScript. To what extent they are compatible with Expo, I don't know. – Topaco Dec 01 '21 at 12:48

0 Answers0