3

I'm trying to send a CryptoKey (generated by SubtleCrypto.generateKey()) object from a contentscript to the background page of a webextension.

When using chrome.runtime.sendMessage to send the object, it is lost, as CryptoKey is not stringifyable (see also this question). Using window.postMessage to transfer the key to another window does work, as this method uses structured cloning..

Is there something similar to postMessage to send data that is not stringifyable to the background page of a webextension?

BenjaminH
  • 324
  • 3
  • 13
  • 3
    The only workaround is to create an iframe in the content script, pointing to an html file inside the extension (exposed via [web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources)), postMessage the key there. Inside the iframe you can either directly invoke a global method from the background script via chrome.extension.getBackgroundPage or use BroadcastChannel API). – wOxxOm Aug 22 '20 at 11:09
  • That way the key is only available when the user has the page containing it open . Sadly this is not an option. (Edit: I think I misunderstood you at first. I'm going to try that) – BenjaminH Aug 22 '20 at 11:31
  • @wOxxOm really cool, it works. If you post this as answer, I'm happy to accept it :) – BenjaminH Aug 23 '20 at 09:49
  • If you post an answer with the actual code it'd be better. – wOxxOm Aug 23 '20 at 10:15

1 Answers1

2

Thanks to the comment by @wOxxOm I solved it by creating a web accessible resource with this code:

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
  chrome.extension.getBackgroundPage().postMessage(event.data, "*");
}

This is triggered by the contentscript like that:

let iframe = document.createElement('iframe');
iframe.setAttribute('src', chrome.extension.getURL('webaccessible/index.html'));
iframe.addEventListener("load", () => {
  iframe.contentWindow.postMessage(data);
})

While data is an object that contains the CryptoKey.

This data is received in the background script just like you normally would receive such messages:

window.addEventListener('message',(event) => {
  console.log(event);
});
BenjaminH
  • 324
  • 3
  • 13