PeculiarVentures / webcrypto-liner

webcrypto-liner is a polyfill that let's down-level User Agents (like IE/Edge) use libraries that depend on WebCrypto. (Keywords: Javascript, WebCrypto, Shim, Polyfill)
MIT License
149 stars 26 forks source link

Problem with iOS safari importKey AES-GCM #50

Closed borisreitman closed 6 years ago

borisreitman commented 6 years ago

Here's the sample code:

<HTML>
<head>
    <meta charset="UTF-8">
    <title>WebCrypto Liner</title>
    <script src="../../dist/webcrypto-liner.shim.js"></script>
    <script src="../src/asmcrypto.min.js"></script>
</head>
<body>
    <script>
        function write_debug(txt){
          var div = document.createElement("div");
          document.body.appendChild(div);
          div.innerHTML = txt;
        }
        function test1(){
          var key_data = new Uint8Array([
            1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
            1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
          ]);
          crypto.subtle.importKey(
            "raw", //can be "jwk" or "raw"
            key_data.buffer,
            { name: "AES-GCM", length: 256 },
            true, // this should be the extractable flag
            ["encrypt","decrypt","wrapKey","unwrapKey"]
          ).then(function(key_obj){
            console.log("Y2");
            write_debug("Y2");
            return crypto.subtle.exportKey("jwk", key_obj);
          }).catch(function(err){
            console.error("Y3 error: ",err);
            write_debug("Y3 error: "+err);
          }).then(function(keydata){
            console.log("Y4");
            write_debug("Y4");
          }).catch(function(err){
            console.error("Y5 error: ",err);
            write_debug("Y5 error: "+err);
          });
        }

        function write_debug(txt){
          var div = document.createElement("div");
          document.body.appendChild(div);
          div.innerHTML = txt;
        }
        test1();
   </script>
</BODY></HTML> 

It works on OSX Safari, but it doesn't work on my iPhone safari (iOS version 10.3.2). The error output is:

Y2
Y3 error: Error: CryptoKey is not extractable
Y4

Please note that I am passing in the sample "true" for the extractable flag.

Version of of my webcrypto-liner git checkout is bd4cff569f7afe335de3904839ddf815674e483c which has the comment 0.1.28 -- so it must be a version release.

microshine commented 6 years ago

@borisreitman Thanks. I'll fix it soon

microshine commented 6 years ago

@borisreitman I published v1.0.32 You can try your test script here https://microshine.github.io/test-webcrypto/

borisreitman commented 6 years ago

Why has this worked on OSX Safari, without any modifications ?

rmhrisk commented 6 years ago

@borisreitman liner has browser specific special casing in it, while I didn't look at the PR differences in the version just published it could be related to that.

microshine commented 6 years ago

Because OSX Safari has native implementation for this algorithm. iOS Safari uses JS implementation

doraemondrian commented 6 years ago

Hi guys, first of all thank you so much for this library and the node shim, I can't imagine how i could have ported all the webcrypto powered apps to work with older browsers.

Anyway, I ran into the same problem, but for exporting RSA-OAEP.

I can confirm that it works for the above example with AES-GCM, but not for RSA-OAEP.

Here's the code (Pretty much the same, except I'm trying to export an RSA key)

<HTML>
<head>
    <meta charset="UTF-8">
    <title>WebCrypto Liner</title>
    <script src="https://microshine.github.io/test-webcrypto/webcrypto-liner.shim.js"></script>
    <script src="https://microshine.github.io/test-webcrypto/asmcrypto.min.js"></script>
</head>

<body>
    <script>
        function test2() {
            crypto.subtle.generateKey(
              {
                name: "RSA-OAEP",
                modulusLength: 2048,
                publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
                hash: {name: "SHA-256"},
              },
              true,
              ["encrypt", "decrypt"]
            ).then(function(key) {
              console.log("key = ", key);
              return crypto.subtle.exportKey("jwk", key.publicKey)
            }).catch(function (err) {
                console.error("Y3 error: ", err);
                write_debug("Y3 error: " + err);
            }).then(function (keydata) {
                console.log("Y4");
                write_debug("Y4");
            })
        }
        function write_debug(txt) {
            var div = document.createElement("div");
            document.body.appendChild(div);
            div.innerHTML = txt;
        }
        test1();
    </script>
</BODY>
</HTML>

I get an "Y3 error: Error: Cannot export native CryptoKey from JS implementation".

I'm using iOS 10 safari on an iPad.

rmhrisk commented 6 years ago

@doraemondrian please create a new bug for this issue.

doraemondrian commented 6 years ago

@rmhrisk Done. First thought these were related issues, sorry about that!