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 Introduction

Web Cryptography API Examples

Live Table: https://diafygi.github.io/webcrypto-examples/

I couldn't find anywhere that had clear examples of WebCryptoAPI, so I wrote examples and made a live table with them. Pull requests welcome!

  1. RSASSA-PKCS1-v1_5
  1. RSA-PSS
  1. RSA-OAEP
  1. ECDSA
  1. ECDH
  1. AES-CTR
  1. AES-CBC
  1. AES-CMAC
  1. AES-GCM
  1. AES-CFB
  1. AES-KW
  1. HMAC
  1. DH
  1. SHA
  1. CONCAT
  1. HKDF-CTR
  1. PBKDF2

RSASSA-PKCS1-v1_5

RSASSA-PKCS1-v1_5 - generateKey

window.crypto.subtle.generateKey(
    {
        name: "RSASSA-PKCS1-v1_5",
        modulusLength: 2048, //can be 1024, 2048, or 4096
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        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"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns a keypair object
    console.log(key);
    console.log(key.publicKey);
    console.log(key.privateKey);
})
.catch(function(err){
    console.error(err);
});

RSASSA-PKCS1-v1_5 - importKey

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,
    },
    {   //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)
    ["verify"] //"verify" for public key import, "sign" for private key imports
)
.then(function(publicKey){
    //returns a publicKey (or privateKey if you are importing a private key)
    console.log(publicKey);
})
.catch(function(err){
    console.error(err);
});

RSASSA-PKCS1-v1_5 - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
    publicKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

RSASSA-PKCS1-v1_5 - sign

window.crypto.subtle.sign(
    {
        name: "RSASSA-PKCS1-v1_5",
    },
    privateKey, //from generateKey or importKey above
    data //ArrayBuffer of data you want to sign
)
.then(function(signature){
    //returns an ArrayBuffer containing the signature
    console.log(new Uint8Array(signature));
})
.catch(function(err){
    console.error(err);
});

RSASSA-PKCS1-v1_5 - verify

window.crypto.subtle.verify(
    {
        name: "RSASSA-PKCS1-v1_5",
    },
    publicKey, //from generateKey or importKey above
    signature, //ArrayBuffer of the signature
    data //ArrayBuffer of the data
)
.then(function(isvalid){
    //returns a boolean on whether the signature is true or not
    console.log(isvalid);
})
.catch(function(err){
    console.error(err);
});

RSA-PSS

RSA-PSS - generateKey

window.crypto.subtle.generateKey(
    {
        name: "RSA-PSS",
        modulusLength: 2048, //can be 1024, 2048, or 4096
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        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"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns a keypair object
    console.log(key);
    console.log(key.publicKey);
    console.log(key.privateKey);
})
.catch(function(err){
    console.error(err);
});

RSA-PSS - importKey

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: "PS256",
        ext: true,
    },
    {   //these are the algorithm options
        name: "RSA-PSS",
        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)
    ["verify"] //"verify" for public key import, "sign" for private key imports
)
.then(function(publicKey){
    //returns a publicKey (or privateKey if you are importing a private key)
    console.log(publicKey);
})
.catch(function(err){
    console.error(err);
});

RSA-PSS - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
    publicKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

RSA-PSS - sign

window.crypto.subtle.sign(
    {
        name: "RSA-PSS",
        saltLength: 128, //the length of the salt
    },
    privateKey, //from generateKey or importKey above
    data //ArrayBuffer of data you want to sign
)
.then(function(signature){
    //returns an ArrayBuffer containing the signature
    console.log(new Uint8Array(signature));
})
.catch(function(err){
    console.error(err);
});

RSA-PSS - verify

window.crypto.subtle.verify(
    {
        name: "RSA-PSS",
        saltLength: 128, //the length of the salt
    },
    publicKey, //from generateKey or importKey above
    signature, //ArrayBuffer of the signature
    data //ArrayBuffer of the data
)
.then(function(isvalid){
    //returns a boolean on whether the signature is true or not
    console.log(isvalid);
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP

RSA-OAEP - generateKey

window.crypto.subtle.generateKey(
    {
        name: "RSA-OAEP",
        modulusLength: 2048, //can be 1024, 2048, or 4096
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        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)
    ["encrypt", "decrypt"] //must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
)
.then(function(key){
    //returns a keypair object
    console.log(key);
    console.log(key.publicKey);
    console.log(key.privateKey);
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP - importKey

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: "RSA-OAEP-256",
        ext: true,
    },
    {   //these are the algorithm options
        name: "RSA-OAEP",
        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)
    ["encrypt"] //"encrypt" or "wrapKey" for public key import or
                //"decrypt" or "unwrapKey" for private key imports
)
.then(function(publicKey){
    //returns a publicKey (or privateKey if you are importing a private key)
    console.log(publicKey);
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
    publicKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP - encrypt

window.crypto.subtle.encrypt(
    {
        name: "RSA-OAEP",
        //label: Uint8Array([...]) //optional
    },
    publicKey, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(encrypted));
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP - decrypt

window.crypto.subtle.decrypt(
    {
        name: "RSA-OAEP",
        //label: Uint8Array([...]) //optional
    },
    privateKey, //from generateKey or importKey above
    data //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP - wrapKey

window.crypto.subtle.wrapKey(
    "raw", //the export format, must be "raw" (only available sometimes)
    key, //the key you want to wrap, must be able to fit in RSA-OAEP padding
    publicKey, //the public key with "wrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "RSA-OAEP",
        hash: {name: "SHA-256"},
    }
)
.then(function(wrapped){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(wrapped));
})
.catch(function(err){
    console.error(err);
});

RSA-OAEP - unwrapKey

window.crypto.subtle.unwrapKey(
    "raw", //the import format, must be "raw" (only available sometimes)
    wrapped, //the key you want to unwrap
    privateKey, //the private key with "unwrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        hash: {name: "SHA-256"},
    },
    {   //this what you want the wrapped key to become (same as when wrapping)
        name: "AES-GCM",
        length: 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //the usages you want the unwrapped key to have
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

ECDSA

ECDSA - generateKey

window.crypto.subtle.generateKey(
    {
        name: "ECDSA",
        namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns a keypair object
    console.log(key);
    console.log(key.publicKey);
    console.log(key.privateKey);
})
.catch(function(err){
    console.error(err);
});

ECDSA - importKey

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: "EC",
        crv: "P-256",
        x: "zCQ5BPHPCLZYgdpo1n-x_90P2Ij52d53YVwTh3ZdiMo",
        y: "pDfQTUx0-OiZc5ZuKMcA7v2Q7ZPKsQwzB58bft0JTko",
        ext: true,
    },
    {   //these are the algorithm options
        name: "ECDSA",
        namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["verify"] //"verify" for public key import, "sign" for private key imports
)
.then(function(publicKey){
    //returns a publicKey (or privateKey if you are importing a private key)
    console.log(publicKey);
})
.catch(function(err){
    console.error(err);
});

ECDSA - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
    publicKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

ECDSA - sign

window.crypto.subtle.sign(
    {
        name: "ECDSA",
        hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    privateKey, //from generateKey or importKey above
    data //ArrayBuffer of data you want to sign
)
.then(function(signature){
    //returns an ArrayBuffer containing the signature
    console.log(new Uint8Array(signature));
})
.catch(function(err){
    console.error(err);
});

ECDSA - verify

window.crypto.subtle.verify(
    {
        name: "ECDSA",
        hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    publicKey, //from generateKey or importKey above
    signature, //ArrayBuffer of the signature
    data //ArrayBuffer of the data
)
.then(function(isvalid){
    //returns a boolean on whether the signature is true or not
    console.log(isvalid);
})
.catch(function(err){
    console.error(err);
});

ECDH

ECDH - generateKey

window.crypto.subtle.generateKey(
    {
        name: "ECDH",
        namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
    //returns a keypair object
    console.log(key);
    console.log(key.publicKey);
    console.log(key.privateKey);
})
.catch(function(err){
    console.error(err);
});

ECDH - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
    {   //this is an example jwk key, other key types are Uint8Array objects
        kty: "EC",
        crv: "P-256",
        x: "kgR_PqO07L8sZOBbw6rvv7O_f7clqDeiE3WnMkb5EoI",
        y: "djI-XqCqSyO9GFk_QT_stROMCAROIvU8KOORBgQUemE",
        d: "5aPFSt0UFVXYGu-ZKyC9FQIUOAMmnjzdIwkxCMe3Iok",
        ext: true,
    },
    {   //these are the algorithm options
        name: "ECDH",
        namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //"deriveKey" and/or "deriveBits" for private keys only (just put an empty list if importing a public key)
)
.then(function(privateKey){
    //returns a privateKey (or publicKey if you are importing a public key)
    console.log(privateKey);
})
.catch(function(err){
    console.error(err);
});

ECDH - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" (public or private), "raw" (public only), "spki" (public only), or "pkcs8" (private only)
    publicKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

ECDH - deriveKey

window.crypto.subtle.deriveKey(
    {
        name: "ECDH",
        namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
        public: publicKey, //an ECDH public key from generateKey or importKey
    },
    privateKey, //your ECDH private key from generateKey or importKey
    { //the key type you want to create based on the derived bits
        name: "AES-CTR", //can be any AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
        //the generateKey parameters for that type of algorithm
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the derived key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

ECDH - deriveBits

window.crypto.subtle.deriveBits(
    {
        name: "ECDH",
        namedCurve: "P-256", //can be "P-256", "P-384", or "P-521"
        public: publicKey, //an ECDH public key from generateKey or importKey
    },
    privateKey, //your ECDH private key from generateKey or importKey
    256 //the number of bits you want to derive
)
.then(function(bits){
    //returns the derived bits as an ArrayBuffer
    console.log(new Uint8Array(bits));
})
.catch(function(err){
    console.error(err);
});

AES-CTR

AES-CTR - generateKey

window.crypto.subtle.generateKey(
    {
        name: "AES-CTR",
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CTR - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256CTR",
        ext: true,
    },
    {   //this is the algorithm options
        name: "AES-CTR",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CTR - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

AES-CTR - encrypt

window.crypto.subtle.encrypt(
    {
        name: "AES-CTR",
        //Don't re-use counters!
        //Always use a new counter every time your encrypt!
        counter: new Uint8Array(16),
        length: 128, //can be 1-128
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(encrypted));
})
.catch(function(err){
    console.error(err);
});

AES-CTR - decrypt

window.crypto.subtle.decrypt(
    {
        name: "AES-CTR",
        counter: ArrayBuffer(16), //The same counter you used to encrypt
        length: 128, //The same length you used to encrypt
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    console.error(err);
});

AES-CTR - wrapKey

window.crypto.subtle.wrapKey(
    "jwk", //can be "jwk", "raw", "spki", or "pkcs8"
    key, //the key you want to wrap, must be able to export to "raw" format
    wrappingKey, //the AES-CTR key with "wrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-CTR",
        //Don't re-use counters!
        //Always use a new counter every time your encrypt!
        counter: new Uint8Array(16),
        length: 128, //can be 1-128
    }
)
.then(function(wrapped){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(wrapped));
})
.catch(function(err){
    console.error(err);
});

AES-CTR - unwrapKey

window.crypto.subtle.unwrapKey(
    "jwk", //"jwk", "raw", "spki", or "pkcs8" (whatever was used in wrapping)
    wrapped, //the key you want to unwrap
    wrappingKey, //the AES-CTR key with "unwrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-CTR",
        //Don't re-use counters!
        //Always use a new counter every time your encrypt!
        counter: new Uint8Array(16),
        length: 128, //can be 1-128
    },
    {   //this what you want the wrapped key to become (same as when wrapping)
        name: "AES-GCM",
        length: 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //the usages you want the unwrapped key to have
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CBC

AES-CBC - generateKey

window.crypto.subtle.generateKey(
    {
        name: "AES-CBC",
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can be "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CBC - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256CBC",
        ext: true,
    },
    {   //this is the algorithm options
        name: "AES-CBC",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can be "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CBC - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

AES-CBC - encrypt

window.crypto.subtle.encrypt(
    {
        name: "AES-CBC",
        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        iv: window.crypto.getRandomValues(new Uint8Array(16)),
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(encrypted));
})
.catch(function(err){
    console.error(err);
});

AES-CBC - decrypt

window.crypto.subtle.decrypt(
    {
        name: "AES-CBC",
        iv: ArrayBuffer(16), //The initialization vector you used to encrypt
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    console.error(err);
});

AES-CBC - wrapKey

window.crypto.subtle.wrapKey(
    "jwk", //can be "jwk", "raw", "spki", or "pkcs8"
    key, //the key you want to wrap, must be able to export to above format
    wrappingKey, //the AES-CBC key with "wrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-CBC",
        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        iv: window.crypto.getRandomValues(new Uint8Array(16)),
    }
)
.then(function(wrapped){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(wrapped));
})
.catch(function(err){
    console.error(err);
});

AES-CBC - unwrapKey

window.crypto.subtle.unwrapKey(
    "jwk", //"jwk", "raw", "spki", or "pkcs8" (whatever was used in wrapping)
    wrapped, //the key you want to unwrap
    wrappingKey, //the AES-CBC key with "unwrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-CBC",
        iv: ArrayBuffer(16), //The initialization vector you used to encrypt
    },
    {   //this what you want the wrapped key to become (same as when wrapping)
        name: "AES-GCM",
        length: 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //the usages you want the unwrapped key to have
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CMAC

AES-CMAC - generateKey

window.crypto.subtle.generateKey(
    {
        name: "AES-CMAC",
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CMAC - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256CMAC",
        ext: true,
    },
    {   //this is the algorithm options
        name: "AES-CMAC",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CMAC - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

AES-CMAC - sign

window.crypto.subtle.sign(
    {
        name: "AES-CMAC",
        length: 256, //bit length of the MAC
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to sign
)
.then(function(signature){
    //returns an ArrayBuffer containing the signature
    console.log(new Uint8Array(signature));
})
.catch(function(err){
    console.error(err);
});

AES-CMAC - verify

window.crypto.subtle.verify(
    {
        name: "AES-CMAC",
        length: 256, //bit length of the MAC
    },
    key, //from generateKey or importKey above
    signature, //ArrayBuffer of the signature
    data //ArrayBuffer of the data
)
.then(function(isvalid){
    //returns a boolean on whether the signature is true or not
    console.log(isvalid);
})
.catch(function(err){
    console.error(err);
});

AES-GCM

AES-GCM - generateKey

window.crypto.subtle.generateKey(
    {
        name: "AES-GCM",
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-GCM - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256GCM",
        ext: true,
    },
    {   //this is the algorithm options
        name: "AES-GCM",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-GCM - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

AES-GCM - encrypt

window.crypto.subtle.encrypt(
    {
        name: "AES-GCM",

        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        //Recommended to use 12 bytes length
        iv: window.crypto.getRandomValues(new Uint8Array(12)),

        //Additional authentication data (optional)
        additionalData: ArrayBuffer,

        //Tag length (optional)
        tagLength: 128, //can be 32, 64, 96, 104, 112, 120 or 128 (default)
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(encrypted));
})
.catch(function(err){
    console.error(err);
});

AES-GCM - decrypt

window.crypto.subtle.decrypt(
    {
        name: "AES-GCM",
        iv: ArrayBuffer(12), //The initialization vector you used to encrypt
        additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any)
        tagLength: 128, //The tagLength you used to encrypt (if any)
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    console.error(err);
});

AES-GCM - wrapKey

window.crypto.subtle.wrapKey(
    "jwk", //can be "jwk", "raw", "spki", or "pkcs8"
    key, //the key you want to wrap, must be able to export to above format
    wrappingKey, //the AES-GCM key with "wrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-GCM",

        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        //Recommended to use 12 bytes length
        iv: window.crypto.getRandomValues(new Uint8Array(12)),

        //Additional authentication data (optional)
        additionalData: ArrayBuffer,

        //Tag length (optional)
        tagLength: 128, //can be 32, 64, 96, 104, 112, 120 or 128 (default)
    }
)
.then(function(wrapped){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(wrapped));
})
.catch(function(err){
    console.error(err);
});

AES-GCM - unwrapKey

window.crypto.subtle.unwrapKey(
    "jwk", //"jwk", "raw", "spki", or "pkcs8" (whatever was used in wrapping)
    wrapped, //the key you want to unwrap
    wrappingKey, //the AES-GCM key with "unwrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-GCM",
        iv: ArrayBuffer(12), //The initialization vector you used to encrypt
        additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any)
        tagLength: 128, //The tagLength you used to encrypt (if any)
    },
    {   //this what you want the wrapped key to become (same as when wrapping)
        name: "AES-CBC",
        length: 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //the usages you want the unwrapped key to have
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CFB

AES-CFB - generateKey

window.crypto.subtle.generateKey(
    {
        name: "AES-CFB-8",
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CFB - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256CFB8",
        ext: true,
    },
    {   //this is the algorithm options
        name: "AES-CFB-8",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-CFB - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

AES-CFB - encrypt

window.crypto.subtle.encrypt(
    {
        name: "AES-CFB-8",
        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        iv: window.crypto.getRandomValues(new Uint8Array(16)),
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(encrypted));
})
.catch(function(err){
    console.error(err);
});

AES-CFB - decrypt

window.crypto.subtle.decrypt(
    {
        name: "AES-CFB-8",
        iv: ArrayBuffer(16), //The initialization vector you used to encrypt
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of the data
)
.then(function(decrypted){
    //returns an ArrayBuffer containing the decrypted data
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    console.error(err);
});

AES-CFB - wrapKey

window.crypto.subtle.wrapKey(
    "jwk", //can be "jwk", "raw", "spki", or "pkcs8"
    key, //the key you want to wrap, must be able to export to above format
    wrappingKey, //the AES-CFB key with "wrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-CFB",
        //Don't re-use initialization vectors!
        //Always generate a new iv every time your encrypt!
        iv: window.crypto.getRandomValues(new Uint8Array(16)),
    }
)
.then(function(wrapped){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(wrapped));
})
.catch(function(err){
    console.error(err);
});

AES-CFB - unwrapKey

window.crypto.subtle.unwrapKey(
    "jwk", //"jwk", "raw", "spki", or "pkcs8" (whatever was used in wrapping)
    wrapped, //the key you want to unwrap
    wrappingKey, //the AES-CFB key with "unwrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-CFB",
        iv: ArrayBuffer(16), //The initialization vector you used to encrypt
    },
    {   //this what you want the wrapped key to become (same as when wrapping)
        name: "AES-GCM",
        length: 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //the usages you want the unwrapped key to have
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-KW

AES-KW - generateKey

window.crypto.subtle.generateKey(
    {
        name: "AES-KW",
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["wrapKey", "unwrapKey"] //can be any combination of "wrapKey" and "unwrapKey"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-KW - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256KW",
        ext: true,
    },
    {   //this is the algorithm options
        name: "AES-KW",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["wrapKey", "unwrapKey"] //can be any combination of "wrapKey" and "unwrapKey"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

AES-KW - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

AES-KW - wrapKey

window.crypto.subtle.wrapKey(
    "raw", //the export format, must be "raw" (only available sometimes)
    key, //the key you want to wrap, must export in 8 byte increments
    wrappingKey, //the AES-KW key with "wrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-KW",
    }
)
.then(function(wrapped){
    //returns an ArrayBuffer containing the encrypted data
    console.log(new Uint8Array(wrapped));
})
.catch(function(err){
    console.error(err);
});

AES-KW - unwrapKey

window.crypto.subtle.unwrapKey(
    "raw", //the import format, must be "raw" (only available sometimes)
    wrapped, //the key you want to unwrap
    wrappingKey, //the AES-KW key with "unwrapKey" usage flag
    {   //these are the wrapping key's algorithm options
        name: "AES-KW",
    },
    {   //this what you want the wrapped key to become (same as when wrapping)
        name: "AES-GCM",
        length: 256
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //the usages you want the unwrapped key to have
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

HMAC

HMAC - generateKey

window.crypto.subtle.generateKey(
    {
        name: "HMAC",
        hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
        //length: 256, //optional, if you want your key length to differ from the hash function's block length
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

HMAC - importKey

window.crypto.subtle.importKey(
    "jwk", //can be "jwk" or "raw"
    {   //this is an example jwk key, "raw" would be an ArrayBuffer
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "HS256",
        ext: true,
    },
    {   //this is the algorithm options
        name: "HMAC",
        hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
        //length: 256, //optional, if you want your key length to differ from the hash function's block length
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function(key){
    //returns the symmetric key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

HMAC - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "jwk" or "raw"
    key //extractable must be true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

HMAC - sign

window.crypto.subtle.sign(
    {
        name: "HMAC",
    },
    key, //from generateKey or importKey above
    data //ArrayBuffer of data you want to sign
)
.then(function(signature){
    //returns an ArrayBuffer containing the signature
    console.log(new Uint8Array(signature));
})
.catch(function(err){
    console.error(err);
});

HMAC - verify

window.crypto.subtle.verify(
    {
        name: "HMAC",
    },
    key, //from generateKey or importKey above
    signature, //ArrayBuffer of the signature
    data //ArrayBuffer of the data
)
.then(function(isvalid){
    //returns a boolean on whether the signature is true or not
    console.log(isvalid);
})
.catch(function(err){
    console.error(err);
});

DH

DH - generateKey

window.crypto.subtle.generateKey(
    {
        name: "DH",
        //NOTE: THIS IS A SMALL PRIME FOR TESTING ONLY! DO NOT USE IT FOR REAL!
        //See http://datatracker.ietf.org/doc/rfc3526/ for better primes
        prime: new Uint8Array([
            255,255,255,255,255,255,255,255,201,15,218,162,33,104,194,52,196,198,98,139,
            128,220,28,209,41,2,78,8,138,103,204,116,2,11,190,166,59,19,155,34,81,74,8,
            121,142,52,4,221,239,149,25,179,205,58,67,27,48,43,10,109,242,95,20,55,79,225,
            53,109,109,81,194,69,228,133,181,118,98,94,126,198,244,76,66,233,166,55,237,
            107,11,255,92,182,244,6,183,237,238,56,107,251,90,137,159,165,174,159,36,17,
            124,75,31,230,73,40,102,81,236,228,91,61,194,0,124,184,161,99,191,5,152,218,
            72,54,28,85,211,154,105,22,63,168,253,36,207,95,131,101,93,35,220,163,173,
            150,28,98,243,86,32,133,82,187,158,213,41,7,112,150,150,109,103,12,53,78,74,
            188,152,4,241,116,108,8,202,35,115,39,255,255,255,255,255,255,255,255
        ]),
        generator: new Uint8Array([2]),
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
    //returns a keypair object
    console.log(key);
    console.log(key.publicKey);
    console.log(key.privateKey);
})
.catch(function(err){
    console.error(err);
});

DH - importKey

window.crypto.subtle.importKey(
    "raw", //can be "raw" (public only), "spki" (public only), or "pkcs8" (private only)
    new Uint8Array([ //this is an example raw key, "raw" would be an ArrayBuffer
        203,25,0,203,43,75,46,159,217,37,185,181,25,220,71,187,112,195,251,233,152,56,206,
        93,18,96,87,132,17,113,166,110,123,190,194,168,100,147,21,174,131,80,8,247,125,35,
        210,70,103,141,152,173,99,74,34,132,92,134,216,55,171,186,89,167,189,217,164,119,
        22,139,55,26,239,242,30,241,140,139,202,116,174,137,77,11,29,4,30,47,118,170,84,243,
        97,132,86,58,24,82,36,149,45,185,23,172,67,162,48,43,110,251,175,20,102,237,113,148,
        5,242,29,209,34,173,52,72,251,254,84,86,226,151,202,110,61,145,198,244,80,227,65,
        203,118,217,91,45,58,172,165,224,122,230,50,135,120,124,37,190,186,204,103,218,19,
        91,246,115,6,199,45,121,156,149,6,208,85,26,94,171,165,228,58,200,49,82,210,170,243,
        154,190,15,2,225,143,159
    ]),
    {   //these are the algorithm options
        name: "DH",
        //NOTE: THIS IS A SMALL PRIME FOR TESTING ONLY! DO NOT USE IT FOR REAL!
        //See http://datatracker.ietf.org/doc/rfc3526/ for better primes
        prime: new Uint8Array([
            255,255,255,255,255,255,255,255,201,15,218,162,33,104,194,52,196,198,98,139,
            128,220,28,209,41,2,78,8,138,103,204,116,2,11,190,166,59,19,155,34,81,74,8,
            121,142,52,4,221,239,149,25,179,205,58,67,27,48,43,10,109,242,95,20,55,79,225,
            53,109,109,81,194,69,228,133,181,118,98,94,126,198,244,76,66,233,166,55,237,
            107,11,255,92,182,244,6,183,237,238,56,107,251,90,137,159,165,174,159,36,17,
            124,75,31,230,73,40,102,81,236,228,91,61,194,0,124,184,161,99,191,5,152,218,
            72,54,28,85,211,154,105,22,63,168,253,36,207,95,131,101,93,35,220,163,173,
            150,28,98,243,86,32,133,82,187,158,213,41,7,112,150,150,109,103,12,53,78,74,
            188,152,4,241,116,108,8,202,35,115,39,255,255,255,255,255,255,255,255
        ]),
        generator: new Uint8Array([2]),
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    [] //use ["deriveKey", "deriveBits"] if importing a private key
)
.then(function(publicKey){
    //returns a publicKey (or privateKey if you are importing a private key)
    console.log(publicKey);
})
.catch(function(err){
    console.error(err);
});

DH - exportKey

window.crypto.subtle.exportKey(
    "jwk", //can be "raw" (public or private), "spki" (public only), or "pkcs8" (private only)
    publicKey //can be a publicKey or privateKey, as long as extractable was true
)
.then(function(keydata){
    //returns the exported key data
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

DH - deriveKey

window.crypto.subtle.deriveKey(
    {
        name: "DH",
        //NOTE: THIS IS A SMALL PRIME FOR TESTING ONLY! DO NOT USE IT FOR REAL!
        //See http://datatracker.ietf.org/doc/rfc3526/ for better primes
        prime: new Uint8Array([
            255,255,255,255,255,255,255,255,201,15,218,162,33,104,194,52,196,198,98,139,
            128,220,28,209,41,2,78,8,138,103,204,116,2,11,190,166,59,19,155,34,81,74,8,
            121,142,52,4,221,239,149,25,179,205,58,67,27,48,43,10,109,242,95,20,55,79,225,
            53,109,109,81,194,69,228,133,181,118,98,94,126,198,244,76,66,233,166,55,237,
            107,11,255,92,182,244,6,183,237,238,56,107,251,90,137,159,165,174,159,36,17,
            124,75,31,230,73,40,102,81,236,228,91,61,194,0,124,184,161,99,191,5,152,218,
            72,54,28,85,211,154,105,22,63,168,253,36,207,95,131,101,93,35,220,163,173,
            150,28,98,243,86,32,133,82,187,158,213,41,7,112,150,150,109,103,12,53,78,74,
            188,152,4,241,116,108,8,202,35,115,39,255,255,255,255,255,255,255,255
        ]),
        generator: new Uint8Array([2]),
        public: publicKey, //a DH public key from generateKey or importKey
    },
    privateKey, //your DH private key from generateKey or importKey
    { //the key type you want to create based on the derived bits
        name: "AES-CTR", //can be any AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
        //the generateKey parameters for that type of algorithm
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the derived key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
)
.then(function(key){
    //returns the derived key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

DH - deriveBits

window.crypto.subtle.deriveBits(
    {
        name: "DH",
        //NOTE: THIS IS A SMALL PRIME FOR TESTING ONLY! DO NOT USE IT FOR REAL!
        //See http://datatracker.ietf.org/doc/rfc3526/ for better primes
        prime: new Uint8Array([
            255,255,255,255,255,255,255,255,201,15,218,162,33,104,194,52,196,198,98,139,
            128,220,28,209,41,2,78,8,138,103,204,116,2,11,190,166,59,19,155,34,81,74,8,
            121,142,52,4,221,239,149,25,179,205,58,67,27,48,43,10,109,242,95,20,55,79,225,
            53,109,109,81,194,69,228,133,181,118,98,94,126,198,244,76,66,233,166,55,237,
            107,11,255,92,182,244,6,183,237,238,56,107,251,90,137,159,165,174,159,36,17,
            124,75,31,230,73,40,102,81,236,228,91,61,194,0,124,184,161,99,191,5,152,218,
            72,54,28,85,211,154,105,22,63,168,253,36,207,95,131,101,93,35,220,163,173,
            150,28,98,243,86,32,133,82,187,158,213,41,7,112,150,150,109,103,12,53,78,74,
            188,152,4,241,116,108,8,202,35,115,39,255,255,255,255,255,255,255,255
        ]),
        generator: new Uint8Array([2]),
        public: publicKey, //a DH public key from generateKey or importKey
    },
    privateKey, //your DH private key from generateKey or importKey
    256 //the number of bits you want to derive
)
.then(function(bits){
    //returns the derived bits as an ArrayBuffer
    console.log(new Uint8Array(bits));
})
.catch(function(err){
    console.error(err);
});

SHA

SHA-1 - digest

window.crypto.subtle.digest(
    {
        name: "SHA-1",
    },
    new Uint8Array([1,2,3,4]) //The data you want to hash as an ArrayBuffer
)
.then(function(hash){
    //returns the hash as an ArrayBuffer
    console.log(new Uint8Array(hash));
})
.catch(function(err){
    console.error(err);
});

SHA-256 - digest

window.crypto.subtle.digest(
    {
        name: "SHA-256",
    },
    new Uint8Array([1,2,3,4]) //The data you want to hash as an ArrayBuffer
)
.then(function(hash){
    //returns the hash as an ArrayBuffer
    console.log(new Uint8Array(hash));
})
.catch(function(err){
    console.error(err);
});

SHA-384 - digest

window.crypto.subtle.digest(
    {
        name: "SHA-384",
    },
    new Uint8Array([1,2,3,4]) //The data you want to hash as an ArrayBuffer
)
.then(function(hash){
    //returns the hash as an ArrayBuffer
    console.log(new Uint8Array(hash));
})
.catch(function(err){
    console.error(err);
});

SHA-512 - digest

window.crypto.subtle.digest(
    {
        name: "SHA-512",
    },
    new Uint8Array([1,2,3,4]) //The data you want to hash as an ArrayBuffer
)
.then(function(hash){
    //returns the hash as an ArrayBuffer
    console.log(new Uint8Array(hash));
})
.catch(function(err){
    console.error(err);
});

CONCAT

CONCAT - importKey

window.crypto.subtle.importKey(
    "raw", //only "raw" is allowed
    keydata, //your raw key data as an ArrayBuffer
    {
        name: "CONCAT",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

CONCAT - deriveKey

window.crypto.subtle.deriveKey(
    {
        "name": "CONCAT",
        algorithmId: ArrayBuffer, //?????? I don't know what this should be
        partyUInfo: ArrayBuffer, //?????? I don't know what this should be
        partyVInfo: ArrayBuffer, //?????? I don't know what this should be
        publicInfo: ArrayBuffer, //?????? I don't know what this should be
        privateInfo: ArrayBuffer, //?????? I don't know what this should be
        hash: {name: "SHA-1"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    key, //your key from importKey
    { //the key type you want to create based on the derived bits
        name: "AES-CTR", //can be any AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
        //the generateKey parameters for that type of algorithm
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the derived key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
)
.then(function(key){
    //returns the derived key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

CONCAT - deriveBits

window.crypto.subtle.deriveBits(
    {
        "name": "CONCAT",
        algorithmId: ArrayBuffer, //?????? I don't know what this should be
        partyUInfo: ArrayBuffer, //?????? I don't know what this should be
        partyVInfo: ArrayBuffer, //?????? I don't know what this should be
        publicInfo: ArrayBuffer, //?????? I don't know what this should be
        privateInfo: ArrayBuffer, //?????? I don't know what this should be
        hash: {name: "SHA-1"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    key, //your key importKey
    256 //the number of bits you want to derive
)
.then(function(bits){
    //returns the derived bits as an ArrayBuffer
    console.log(new Uint8Array(bits));
})
.catch(function(err){
    console.error(err);
});

HKDF-CTR

HKDF-CTR - importKey

window.crypto.subtle.importKey(
    "raw", //only "raw" is allowed
    keydata, //your raw key data as an ArrayBuffer
    {
        name: "HKDF-CTR",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

HKDF-CTR - deriveKey

window.crypto.subtle.deriveKey(
    {
        "name": "HKDF-CTR",
        label: ArrayBuffer, //?????? I don't know what this should be
        context: ArrayBuffer, //?????? I don't know what this should be
        hash: {name: "SHA-1"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    key, //your key from importKey
    { //the key type you want to create based on the derived bits
        name: "AES-CTR", //can be any AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
        //the generateKey parameters for that type of algorithm
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the derived key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
)
.then(function(key){
    //returns the derived key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

HKDF-CTR - deriveBits

window.crypto.subtle.deriveBits(
    {
        "name": "HKDF-CTR",
        label: ArrayBuffer, //?????? I don't know what this should be
        context: ArrayBuffer, //?????? I don't know what this should be
        hash: {name: "SHA-1"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    key, //your key importKey
    256 //the number of bits you want to derive
)
.then(function(bits){
    //returns the derived bits as an ArrayBuffer
    console.log(new Uint8Array(bits));
})
.catch(function(err){
    console.error(err);
});

PBKDF2

PBKDF2 - generateKey

//NOTE: This prompts the user to enter a password.
window.crypto.subtle.generateKey(
    {
        name: "PBKDF2",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

PBKDF2 - importKey

window.crypto.subtle.importKey(
    "raw", //only "raw" is allowed
    window.crypto.getRandomValues(new Uint8Array(16)), //your password
    {
        name: "PBKDF2",
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["deriveKey", "deriveBits"] //can be any combination of "deriveKey" and "deriveBits"
)
.then(function(key){
    //returns a key object
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

PBKDF2 - deriveKey

window.crypto.subtle.deriveKey(
    {
        "name": "PBKDF2",
        salt: window.crypto.getRandomValues(new Uint8Array(16)),
        iterations: 1000,
        hash: {name: "SHA-1"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    key, //your key from generateKey or importKey
    { //the key type you want to create based on the derived bits
        name: "AES-CTR", //can be any AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH", or "HMAC")
        //the generateKey parameters for that type of algorithm
        length: 256, //can be  128, 192, or 256
    },
    false, //whether the derived key is extractable (i.e. can be used in exportKey)
    ["encrypt", "decrypt"] //limited to the options in that algorithm's importKey
)
.then(function(key){
    //returns the derived key
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

PBKDF2 - deriveBits

window.crypto.subtle.deriveBits(
    {
        "name": "PBKDF2",
        salt: window.crypto.getRandomValues(new Uint8Array(16)),
        iterations: 1000,
        hash: {name: "SHA-1"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    key, //your key from generateKey or importKey
    256 //the number of bits you want to derive
)
.then(function(bits){
    //returns the derived bits as an ArrayBuffer
    console.log(new Uint8Array(bits));
})
.catch(function(err){
    console.error(err);
});

webcrypto-examples's People

Contributors

axelnennker avatar diafygi avatar jedie avatar kevinutah avatar shade avatar vibornoff avatar zmanian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webcrypto-examples's Issues

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>

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.

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...

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

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".

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.

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.

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).

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!

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,
    },

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);
});

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.

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 ...

Just thank you

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

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

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!

RSA-OAEP wrapKey/unwrapKey

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

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!

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.

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);
});
};

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.

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!

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.

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

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).

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.