GithubHelp home page GithubHelp logo

diafygi / webcrypto-examples Goto Github PK

View Code? Open in Web Editor NEW
1.6K 66.0 194.0 120 KB

Web Cryptography API Examples Demo: https://diafygi.github.io/webcrypto-examples/

License: GNU General Public License v2.0

HTML 100.00%

webcrypto-examples's Issues

How pass PEM key (pem=b64(der)) to importKey?

I exctracted pkcs#8 private key with the help of other JS library (forge). After that I converted pkcs8 to PEM (stripped "BEGIN, END" headers and footers) and tried to give that key to standart web crypto API function:

 window.crypto.subtle.importKey(
  "pkcs8", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
  //der,
  //der.getBytes().buffer,
  b64ToArrayBuffer(PEM_headers_stripped);   
     //b64ToArrayBuffer(PEM_headers_NOT_stripped);              
  {   //these are the algorithm options
   name: "RSASSA-PKCS1-v1_5",
   hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
  },
  false, //whether the key is extractable (i.e. can be used in exportKey)
  ["sign"] //"verify" for public key import, "sign" for private key imports
)
.then ...

and in console recieving message "DataError", code: 0.

You can see above, I tried to pass PEM without stripping headers, passed key in der format but all my efforts failed.

May be you know, how pass a pkcs8 in PEM format to web crypto?

Thanks.

How import (e,n) RSA public key to web crypto?

I'm sorry for asking almost similar question to the previous one but I couldn't resolve it by myself.

How RSA public key to web crypto? pkcs#8 relevant only for private key, for public keys I may specify "raw" or "spki". I tried stripped and not stripped PEM with importKey("raw"...), no success. I also tried "raw" and ArrayBuffer(pubKeytoAsn->toDer.getBytes) and again failed.

It seems I have to manually construct JSON parameter in the example below.

window.crypto.subtle.importKey(
"jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
{   //this is an example jwk key, other key types are Uint8Array objects
    kty: "RSA",
    e: "AQAB",
    n: "vGO3eU16ag9zRkJ4AK8ZUZrjbtp5xWK0LyFMNT8933evJoHeczexMUzSiXaLrEFSyQZortk81zJH3y41MBO_UFDO_X0crAquNrkjZDrf9Scc5-MdxlWU2Jl7Gc4Z18AC9aNibWVmXhgvHYkEoFdLCFG-2Sq-qIyW4KFkjan05IE",
    alg: "RS256",
    ext: true,
},

A saw n and e attributes in my public key but I didn't understand is 'n' valuein JSON a base64 of key's n-array which has 74 elements?

In short, I have e=65537, n=array of 74 integers, how can I convert it to jwk? My algo params are "RSASSA-PKCS1-v1_5", hash: {name: "SHA-256"}.

Thanks.

Just thank you

I just want to say that this is awesome. Thanks a lot ๐Ÿ‘

Source of Recommended/Discouraged algorithms

(I'm not sure if this is appropriate for a github issue but I couldn't find a better place)

In the "Web Cryptography API Live Table" some algorithms are marked as "Recommended" and others are "Discouraged! Only use for backwards compatibility!" What is the source of this classification?

I had a quick look at spec and didn't find it there. Though I did find "suggested" algorithms here and according to the list AES-CBC is suggested/recommended, while according to the project's table it's AES-GCM which is recommended and all other cypher modes are "discouraged".

HMAC output size

One small fix:

By default the HMAC's length parameter is the size of hash function's block, not the size of hash output. So for SHA-1 and SHA-256 that would be 512 bits, for SHA-384 and SHA-512 1024 bits.

This is unlike most other libraries, where the output size is equal to the hash output size.

See http://www.w3.org/TR/WebCryptoAPI/#hmac-keygen-params

Thanks!

False negative for PBKDF2+deriveKey

On my browser (FF 61.0.2 on macOS) the PBKDF2+deriveKey() square is marked N/A, with the tooltip AESCBC is not defined, even though I can actually use PBKDF2+deriveKey() on this browser. Looking at the source code, it seems like the problem is that the AESCBC variable is defined after many of the places that use it, but this only causes a failure when the relevant promises resolve quickly enough.

How to import base64 encoded key?

Hi,

I was experimenting with your examples to try to recreate a browser version of:
https://www.npmjs.com/package/jwt-simple

Here is a gist to explain end goal (although this gist doesn't work):
https://gist.github.com/mattmazzola/1eafd7aea79e082982da203ec0405997

When attempting to import the key I am receiving the error:
undefined:1 Uncaught (in promise) DOMException: The JWK member "k" could not be base64url decoded or contained padding

I was using this example: https://github.com/diafygi/webcrypto-examples#hmac---importkey

I know the trailing equal signs indicate there is padding on the key ==, but I'm not sure how to remove it and still import using the same method. It seems like I would have to convert it to an ArrayBuffer and then remove the trailing 0's somehow, but then if we have to use raw key import it makes using jwk seems less useful and I thought there must be a better way or perhaps the import jwk should just handle this for us.

How to import ECDSA public key from PEM chain?

Thanks for your repo, it was really helpful (if not vital) to get started :)

I have a ECDSA P-384 public key as PEM chain that I fetch from a public URL:

-----BEGIN CERTIFICATE-----
MIIC0DCCAlUCCQDh7ZXFZjOO+jAKBggqhkjOPQQDAjCB0DELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHDAa
BgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24xNTAzBgNVBAsMLEF1dG9ncmFwaCBm
b3IgS2ludG8gU2V0dGluZ3MgRGV2IGVudmlyb25tZW50MRYwFAYDVQQDDA1BdXRv
Z3JhcGggWDVVMScwJQYJKoZIhvcNAQkBFhhzdG9yYWdlLXRlYW1AbW96aWxsYS5j
b20wHhcNMTYwNDI5MTQ1ODA4WhcNMTcwNDI5MTQ1ODA4WjCB0DELMAkGA1UEBhMC
VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcx
HDAaBgNVBAoME01vemlsbGEgQ29ycG9yYXRpb24xNTAzBgNVBAsMLEF1dG9ncmFw
aCBmb3IgS2ludG8gU2V0dGluZ3MgRGV2IGVudmlyb25tZW50MRYwFAYDVQQDDA1B
dXRvZ3JhcGggWDVVMScwJQYJKoZIhvcNAQkBFhhzdG9yYWdlLXRlYW1AbW96aWxs
YS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS12UsecmKNRm4+L+jt1++/dENE
EJIICW7X7q8sbaKKlbZWGkcgHqGWrGrIzK0wgMjtLiRKIwwp7izx+XEgueku7K/o
bAKrURi/twi8DGCWOU7JV4Os+MV+pLLab2ehGWcwCgYIKoZIzj0EAwIDaQAwZgIx
AKtsG9nBvvgc81gHZCiVwYgK6qdw1B9eHloKN6aCRfppth/2vLwn4EaB7cmBiI67
UwIxALKkJz8tMlCloUgFaXuuzcoP16O1EB7l9RNM16hrA7Dz3NWMGCUMxSSYBiFo
WHFmvQ==
-----END CERTIFICATE-----

And would like to import it :

const stripped = pemChain.split("\n").slice(1, -2).join("");
const binaryKey = base64ToBinary(stripped);
const usages = ["verify"]; //"verify" for public key import, "sign" for private key imports
return window.crypto.subtle.importKey("spki", binaryKey, {
      name: "ECDSA",
      namedCurve: "P-384"
    },
    false, //whether the key is extractable (i.e. can be used in exportKey),
    usages
  ).catch((e) => console.error(e));


function base64ToBinary(base64) {
  var binary_string =  window.atob(base64);
  var len = binary_string.length;
  var bytes = new Uint8Array( len );
  for (var i = 0; i < len; i++)        {
      bytes[i] = binary_string.charCodeAt(i);
  }
  return bytes;
}

But it throws with DataError: "Data provided to an operation does not meet requirements" and I can't figure out where to start :)

I will continue to investigate and keep you posted...

Encrypt / Decrypt a string?

I'm working on an example of my own, but I'm having some trouble.
(my example: http://coolaj86.github.io/web-crypto-utahjs-preso)

I found a bit of code to convert back and forth between utf8 and TypedArrays and that seems to be working just fine.
(unibable: https://github.com/coolaj86/unibabel-js)

However, the "encrypted" buffer isn't the length I would expect and it can't be decrypted.

I think I'm missing something. To you see anything out of order here?

'use strict';

var webcrypto = window.crypto || window.msCrypto || window.webkitCrypto || window.mozCrypto;

var keyStr = 'VzC2coGPrvecrigzB38DRLGiwVrgiwnQznyrD9BYxAk=';
var keyBuf = window.Unibabel.base64ToArr(keyStr);
var message = "this is a secret message";
var ivLen = (128 / 8);
var iv = new Uint8Array(ivLen); // defaults to zero
var arrb = window.Unibabel.strToUtf8Arr(message);
var data = arrb.buffer;
console.log('message as buffer', arrb.length);
console.log(arrb);

console.log('keyBuf', keyBuf.length);
console.log(keyBuf);

webcrypto.subtle.importKey(
    "raw",
    keyBuf,
    { name: "AES-CBC" },
    true,
    ["encrypt", "decrypt"]
)
.then(function(key){
    //returns the symmetric key
    console.log('key', key);

    return window.crypto.subtle.encrypt(
        { name: "AES-CBC", iv: iv },
        key, //from generateKey or importKey above
        data //ArrayBuffer of data you want to encrypt
    ).then(function(encrypted){
      //returns an ArrayBuffer containing the encrypted data
      // TODO base64
      //console.log(new Uint8Array(encrypted));
      console.log('encrypted');
      console.log(new Uint8Array(encrypted));
      console.log(new Uint8Array(encrypted).length);

      console.log('encrypted', window.Unibabel.arrToBase64(new Uint8Array(encrypted)));

      window.crypto.subtle.decrypt(
          { name: "AES-CBC", iv: iv },
          key, //from generateKey or importKey above
          data //ArrayBuffer of data you want to encrypt
      )
      .then(function(decrypted){
          //returns an ArrayBuffer containing the encrypted data
          console.log(new Uint8Array(encrypted));
          console.log('decrypted', window.Unibabel.arrToBase64(new Uint8Array(decrypted)));
      })






       // error handling

      .catch(function(err){
          console.error(err);
      });
    })
    .catch(function(err){
        console.error(err);
    });
})
.catch(function(err){
    console.error(err);
});

Why are RSA APIs marked as "not recommended"?

Hi, thanks for this, this has been my #1 frequently visited website in the last couple of months.

I have a question. When I look at the demo page at https://diafygi.github.io/webcrypto-examples/ I understand why some of them are "not recommended" and colored out as red, but don't understand why all the RSA APIs are marked as "not recommended".

I don't think there's anything wrong with RSA algorithms, in fact some people don't trust ECC algorithms because of a possible NSA backdoor and also the fact that it could be more vulnerable to quantum computing, etc. I think it's all subjective, and I personally plan on using RSA for my application instead of ECC for these reasons. (My application is not resource constrained so don't really need the keys to be short)

I was wondering if I'm seeing this wrong or if there was a reason behind this decision. Thank you!

Derive key with PBKDF2 for HMAC?

Do browsers really support generating HMAC keys with PBKDF2? Both Chrome and Firefox seem to complain when I pass {name:"HMAC"} to deriveKey in the 3rd parameter. I can't seem to find a definitive answer anywhere.

Issue in decryption crypto.subtle encrypted text using RSACryptoServiceProvider

Hi,

I am trying to use RSA public key using RSACryptoServiceProvider and use it for encryption through window.crypto.subtle but ending with Cryptography_OAEPDecoding upon decryption.

//Generating public key:

		var cspParams = new CspParameters { KeyContainerName = containerName };

        using (var rsa = new RSACryptoServiceProvider(cspParams))
        {                
            var rsaparameters = rsa.ExportParameters(true);
            
            var base64ModulusKey =  GetModulusKey(rsaparameters);

            return base64ModulusKey;
        }

Encryption through window.crypto.subtle:

var jwk_base64 = base64ModulusKey.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');

window.crypto.subtle.importKey(
    "jwk",
    {   
        kty: "RSA",
        e: "AQAB",            
        n: jwk_base64,
        alg: "RSA-OAEP-256",            
        ext: true,
    },
    { name: "RSA-OAEP", hash: { name: "sha-256" } },            
    false,
    ["encrypt"]);

window.crypto.subtle.encrypt(
    {          
      name: "RSA-OAEP"          
    },          
    cryptoKey,                         
    inputMessageBytes              
  ).then(function(encrypted){        
    console.log("base64 encrypted text: " + arrayToBase64String(new Uint8Array(encrypted)));
}); 

//Decryption using private key:

		using (var rsa = new RSACryptoServiceProvider(cspParams))
        {
            decryptedBytes = rsa.Decrypt(encryptedBytes, true);                
        } 

Thanks in advance!

IE11 shows errors on 'Live Table'

When I try to run your Live Table on IE11 I see a bunch of errors in the console:

SCRIPT438: Object doesn't support property or method 'then'
webcrypto-examples (127,25)
...

It looks like you are using Promises which IE11 does not support. Perhaps a polyfill will help? https://github.com/jakearchibald/es6-promise

Thanks for the all the examples; very, very helpful!

Real working Web Cryptography API based lib - PKIjs

Guys,
Now you do not want such simple and almost unusefull examples because in PKIjs we got real using of almost all Web Cryptography API algorithm making real PKI / CMS data (certificates, CRL, PKCS#10, OCSP, TSP, CMS Signed Data, CMS Enveloped Data).

ECDH deriveKey example should use HKDF

The ECDH examples output the raw bits from the ECDH secret value, either directly or into the importKey operation of AES-CTR. As I pointed out on the WebCrypto spec page this is not secure as the secret value is not uniformly random. The recommendation is usually to pass the value through some key derivation function such as HKDF including some context information such as the public keys used in the agreement (better: a hash of the full transcript of messages exchanged up to that point). See for instance Chapter 11 of Serious Cryptography for a discussion of the issues with using the shared secret directly.

I think it should be possible to create an example that passes the ECDH secret bits into HKDF and then into AES-CTR importKey.

WebCrypto DOMException with RSA encrypt method

Having the following code I can encrypt a small text file with some small text in it, but when I try with a 1MB text file I get DOMException.

I tried with the same files and even bigger ones with AES and everything worked well. Is there a limit of a file that can be encrypted with RSA-OAEP encrypt method?

var encryptFile = function(keyPair, file) {
var vector = crypto.getRandomValues(new Uint8Array(16));
window.crypto.subtle.encrypt(
{
name: "RSA-OAEP",
iv: vector
//label: Uint8Array([...]) //optional
},
keyPair.publicKey, //from generateKey or importKey above
file//ArrayBuffer of the data
)
.then(function(encrypted){
//returns an ArrayBuffer containing the decrypted data
console.log(encrypted);
})
.catch(function(err){
console.error(err);
});
};

Why { ext: true } for JWK?

You use ext: true in many of the JWK examples. I couldn't find reference to it in the spec at https://tools.ietf.org/html/draft-ietf-jose-json-web-key-41

Is it deprecated? new? What did / does it mean?

    "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
    {   //this is an example jwk key, other key types are Uint8Array objects
        kty: "RSA",
        e: "AQAB",
        n: "vGO3eU16ag9zRkJ4AK8ZUZrjbtp5xWK0LyFMNT8933evJoHeczexMUzSiXaLrEFSyQZortk81zJH3y41MBO_UFDO_X0crAquNrkjZDrf9Scc5-MdxlWU2Jl7Gc4Z18AC9aNibWVmXhgvHYkEoFdLCFG-2Sq-qIyW4KFkjan05IE",
        alg: "RS256",
        ext: true,
    },

how to get output of SHA algorithms as HEX

First, thanks for the great examples.
I'm still a novice with javascript.
I'm trying to mix FileAPI with webcrypto

I would like to select a file in an input type="file" and get the same hash it would obtain when executing sha1sum via terminal

$ sha1sum LICENSE.txt 
23a1f87d806ce0330b3d85485e399a5f9f553409  LICENSE.txt

My current doubt is how transform ArrayBuffer get HEX in same output HEX format of sha1sum Linux command.

my test code is this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
    <body>

        <form action="" enctype="multipart/form-data">
            <p>
                <label for="id_file">File:</label>
                <input id="id_file" name="file_input" type="file">
            </p>

            <p>
                <label for="id_checksum">checksum:</label>
                <input id="id_checksum" maxlength="1000" name="checksum" type="text">
            </p>
        </form>

        <script>
            function arrayBuffer_to_hex(array_b) {
                // what should I do here
                return array_b;
            }

            function handleFileSelect(evt) {
                var files = evt.target.files; // FileList object

                // Loop through the FileList and generate shasum
                for (var i = 0, f; f = files[i]; i++) {

                    // Only process image files.
                    //if (!f.type.match('image.*')) {
                    //    continue;
                    //}

                    var reader = new FileReader();
                    // Closure to capture the file information.
                    reader.onload = (function (theFile) {
                        return function (e) {
                            window.crypto.subtle.digest(
                                    {
                                        name: "SHA-1"
                                    },
                                    e.target.result
                            )
                                    .then(function (hash) {
                                        //
                                        var hex_value = arrayBuffer_to_hex(hash);
                                        console.log(hex_value);
                                        document.getElementById('id_checksum').value = hex_value;

                                    })
                                    .catch(function (err) {
                                        console.error(err);
                                    });
                        };
                    })(f);

                    // Read in the image file as a data URL.
                    reader.readAsArrayBuffer(f);
                }
            }

            document.getElementById('id_file').addEventListener('change', handleFileSelect, false);
        </script>
    </body>
</html>

verbose mode

Hello,

would be useful to be able to switch on verbose (and the loud setting for errors) to get the actual result objects dumped to web console of possible. Could be triggered with a URL parameter or a dropdown control (so you don't need to modify the source on the live page).

(Sorry JS is not my domain otherwise I would provide patch).

importKey RSA-OAEP with SHA-1 not working on safari 11

Hey , I try to use 'importkey' on safari 11 and also on outlook for mac and both I get error.
window.crypto.subtle.importKey( "jwk", { "kty": "RSA", "e": difensoPublicKeyE, "n": difensoPublicKeyN, "alg": "RSA-OAEP", "ext": true }, { / name: "RSA-OAEP", hash: { name: "SHA-1" }, }, true, ["encrypt"] ).then(function (publicKey) {

Then I get this error:
OpeartionTypeError: Member JsonWebKey.kty is required and must be an instance of DOMString

Not matter what I try it's same error... maybe someone can help please?

Thx

RSA-OAEP wrapKey/unwrapKey

Check please those functions.
It seems that algorithm must be the same as for encrypt/decrypt - {name: string, label?: ArrayBufferView}

How to recover public key with ECDSA?

Any suggestions on how to implement public key recovery with WebCrypto ECDSA?

How is (r,s) encoded in the output buffer of sign?
Is it just r = [0,32) and s = [32,64) for curve = P-256 (docs) ?

Seams like elliptic.js implements the recovery and it should be possible to import the recovered public key via jwk back into WebCrypto ...

Describe each encryption a litle bit

It's good with all example but a short summary/desc of what they are good for would be appreciated. Also what the differences between all AES is

crypto.webkitSubtle.encrypt isn't working

Hello! I'm making browser's extensions for every browser. I use webcrypto for chrome and mozilla and it works perfect, but the same code (i replace crypto.subtle to crypto.webkitSubtle) isn't work correctly with Safari. I use RSA-OAEP with Sha-512 hash.
It's correctly generate keys and export them to jwk, but i can't encrypt or decrypt anything with this keys. It is even don't show error just do nothing.
Can you help pls, how use this in Safari?

Thanks in advance.

public key for ecdh

base64 encoded buffers

  • p-256 BNbYUKk5s/QIApkUNNF4BBrQVNHhzkjvqMYGOqzfjBIA2L+wS6mGubHbuhBxMR28hdqiyQ6jxBwf7acREo5rsCY=
  • p-384 BJyWMhw1NwdXV4PikA1hHEOLtE8JtrXSDqn0EVByEujnB82Ksihe66yWy2J6b0ik4zvccFlq5SMQHiAFV6kUwOgoUn+95SvDwTxAZjc2yzjmiS1qby6D20ykZXfKDaT9Qg==
  • p-521 BAA94rPJwztJ8MAdlKyKt75uSvbiEjlpcOXI20sbbKMNlqePKaJZYHFv/7niqAAfL97KnSGnFUrQ/47aMVIIk0dOWQBak+ehcBhBUS9Iewk7EUJaEWAXcTV2zfig7Ut0ii3r4NRITH40nGIePf/FUUnfCadKvGfS7pqzV8135CSk/6Tahw==

I can do a pull as well to add these in

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.