0

Source code: https://github.com/HectorAnadon/Crypto-NodeJS-window.crypto

I am using AES-128-GCM to send an encrypted picture from a node.js server to a service worker (script running in the web browser background) where I am trying to decrypt it. Communication works good because non-encrypted pictures are shown in the web browser.

The PROBLEM is: when I decrypt in the service worker, in the promise cryptoSubtle.decrypt, I get one exception, this is what the console print for me: Decryption error: OperationError: (anonymous function) @ service_worker.js:310

Line 310 in service_worker.js is: console.error("Decryption error: " + err); //Line 310

Do you have any idea about what I am doing wrong? Thank you very much, I really appreciate it.

Here is the encryption code using Crypto Node.js (doc here: https://nodejs.org/api/crypto.html)

// Nodejs encryption with GCM
// Does not work with nodejs v0.10.31
var fs = require('fs');
var crypto = require('crypto');
var algorithm = 'aes-128-gcm';
var key = '3zTvzr3p67VC61jm'; 
// generate a new iv for each encryption
// As this is for testing I always use the same iv
var iv = '60iP0h6vJoEa';


function encrypt(text) {
  var cipher = crypto.createCipheriv(algorithm, key, iv)
  var encrypted = cipher.update(text);
  return encrypted;
}
var text = fs.readFileSync('mustang_encrypted.jpg');
var hw = encrypt(text);

And this is the decryption code in Service worker using window.crypto (doc here: https://developer.mozilla.org/en-US/docs/Web/API/Window/crypto)

//ArrayBuffer of the data we received
function(bodyArrayBuffer) {

    var cryptoObj = crypto;
    var cryptoSubtle = cryptoObj.subtle;

        /*
         *  IMPORT KEY
         */
     string2ArrayBuffer("3zTvzr3p67VC61jm", function (keyBuffer) {          
         console.log("keyBuffer length: " + keyBuffer.byteLength);
         cryptoSubtle.importKey(
            "raw", //can be "jwk" or "raw"
            keyBuffer,
            {   //this is the algorithm options
                name: "AES-GCM",
            },
            false, //whether the key is extractable (i.e. can be used in exportKey)
            ["encrypt", "decrypt"] //can be any combination of "encrypt" and "decrypt"
        ).then(function(key){
            //returns the symmetric key
            /*
             *  DECRYPTION
             */
            string2ArrayBuffer("60iP0h6vJoEa",function (myIV) {
                cryptoSubtle.decrypt(
                        {
                            name: "AES-GCM",
                            iv: myIV, //The initialization vector you used to encrypt
                            tagLength: 128, //The tagLength you used to encrypt
                        },
                        key, //from generateKey or importKey above
                        bodyArrayBuffer //ArrayBuffer of the data
                    )
                    .then(function(decrypted){
                        //returns an ArrayBuffer containing the decrypted data
                        console.log(new Uint8Array(decrypted));
                        //send response
                        var newResponse = new Response(decrypted, init);
                        console.log("Returning \"decrypted\" response!");
                        accept(newResponse);
                    })
                    .catch(function(err){
                        console.error("Decryption error: " + err);  //Line 310
                    });
            });
        })
        .catch(function(err){
            console.error(err);
        });
    });
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
HectorAnadon
  • 86
  • 2
  • 8
  • do you have the full source code of the example available somewhere ? – Sandro Paganotti Jun 09 '15 at 22:07
  • I will create a public github repository so it is available to everybody. – HectorAnadon Jun 12 '15 at 14:43
  • Here is the source code: https://github.com/HectorAnadon/Crypto-NodeJS-window.crypto – HectorAnadon Jun 15 '15 at 07:33
  • It doesn't make sense to me that you would import the key to decrypt as that is not encrypted. You have to make the public private key pair on the browser and send the public key to the nodejs server (or the private key can be intercepted) where it's used to encrypt via publicKey. In this example it's importing I guess the privateKey and decrypting the message too. Maybe that's why the link is 404 now. I can see you'd get the key somehow securely, but I'm just looking to use (subtle)crypto.generateKeyfirst then it's for sure private to the session. – Master James Jan 28 '19 at 08:24
  • Wait a minute AES-GCM generation makes only one key. No public and Private Key Pair? This is definitely confusing me still. – Master James Jan 28 '19 at 09:12

1 Answers1

1

If I remember correctly the window object is not available from within a ServiceWorker, so if you're trying to access window.crypto it will result in an error.

Sandro Paganotti
  • 2,295
  • 16
  • 12