vibornoff / webcrypto-shim Goto Github PK
View Code? Open in Web Editor NEWWeb Cryptography API shim for legacy browsers
Home Page: https://vibornoff.github.io/webcrypto-shim/
License: MIT License
Web Cryptography API shim for legacy browsers
Home Page: https://vibornoff.github.io/webcrypto-shim/
License: MIT License
Added webcrypto-shim from npm:
"version": "0.1.1"
added to html file :
<script src="node_modules/webcrypto-shim/webcrypto-shim.js"></script>
I see it gets loaded and enters this code:
if ( isWebkit ) {
_crypto.subtle = _subtle;
global.Crypto = _Crypto;
global.SubtleCrypto = _SubtleCrypto;
global.CryptoKey = CryptoKey;
}
my code calls crypto.generateKey(algorithmKeyGen, true, ['sign'])
with these options:
var algorithmKeyGen = {
name: 'RSASSA-PKCS1-v1_5',
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // Equivalent to 65537
hash: {
name: 'SHA-256'
}
};
Getting this error (works on chrome) :
Failed to extract public key from keypair TypeError: undefined is not an object (evaluating 'b._key')
I am including this library as a polyfill for an Angular project that is compiled with TypeScript. TypeScript already handles transpiling Promises to ES5, so a supporting promise polyfill library is not required.
When trying to require webcrypto-shim, the included Promise check causes it to throw an exception:
https://github.com/vibornoff/webcrypto-shim/blob/master/webcrypto-shim.js#L21
I can comment this line out and still use the library, however, that requires me to create a locally modified version of it which I would like to avoid having to do (would like to just use NPM). It would be good to provide some way to skip this check. I'm willing to submit a PR if you like, but I am not sure what approach you would like to take. Perhaps some global variable that allows the bypass of the check?
if ( typeof Promise !== 'function' && !window.WebCryptoShimSkipPromiseCheck )
throw "Promise support required";
The following snippet fails in IE11:
var msg = new Uint8Array([ 104, 101, 108, 108, 111 ])
crypto.subtle.generateKey({ name: 'HMAC', hash: { name: 'SHA-256' } }, false, [ 'sign' ])
.then(function(key) {
return crypto.subtle.sign({ name: 'HMAC' }, key, msg)
})
.then(function(digest) {
document.write('HMAC succeeded, digest: ' + new Uint8Array(digest) + '')
})
.catch(function(err) {
console.error(err);
document.write('HMAC failed, check console for error details')
})
It just returns the generic IE11 { type: "error" } event with no info.
Really thankful for this project. Do you mind running a quick npm publish
? v0.1.4
is the latest in npm and it's missing the fix for RSA-OAEP
in IE11.
Have a look at this Stack Overflow question: https://stackoverflow.com/q/33043091
Hi all, thanks for this shim, seems very little info and resources online for shimming old browsers.
It succeeds in importing my json web key (a public key) that I need to verify a message. Below is a code that works in Chrome and Firefox but fails in IE11 (with the webcrypto-shim). I'm also using promise polyfill (not the promize.js, which was throwing strict-mode errors).
var winCrypto = window.crypto || window.msCrypto;
var signatureAlgorithm = {name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' }};
console.log(signatureBase64);
winCrypto.subtle.importKey(
'jwk',
publicKey,
signatureAlgorithm,
false,
['verify']
).then(function(importedPublicKey) {
console.log(importedPublicKey);
winCrypto.subtle.verify(
{
name: 'RSASSA-PKCS1-v1_5'
},
importedPublicKey,
new Uint8Array(base64_decode(signatureBase64)),
new Uint8Array(arrayBufferFromResponse) // my message is arraybuffer
).then(function(isValid){
if (isValid) {
console.log('SIGNATURE IS VALID! :)');
} else {
console.log('SIGNATURE IS INVALID! :(');
}
})
.catch(function(err){
console.log('Error ' + err);
});
}).catch(function(err) {console.log('PUBLIC KEY IMPORT FAILED! ' + err);});
}
Console logs:
C8WGnm8DQNTiTgQMtklg1+sHRs4nYOTax6kjIvd9Fn0jdrtbjJBOWaGG3EZJltlVZJMak9H9HGBWOyiAyqlrQMC7ofTiRlYouK0QqIQrvCvZ5ymfOuQ1uQ3GB4uC7Am6ItLLUrdhk6W5GhL5WTSkTPncMhRWGe2QOzKo4UF6Caejvujsj2krTaO3vCRpSEDhFiLEJ4RHnLm11Iztmj0xJdE8uYSF8BAaqoKI3Q2fr5Bye7jr5ICiOWR9NwuN+zlJ7AvXGw+eXusSqT3znpnsAT1BojS9MZUbI7M3tuRhdqWxg9NCzn7wYxtuSPSyyBuCfUWIE3O04pR7oqAklTZ6gA==
{"type":"public","extractable":false,"algorithm":{"name":"RSASSA-PKCS1-v1_5","hash":{"name":"SHA-256"}},"usages":["verify"]}
Error [object Event]
The same code in Chrome and Firefox return
SIGNATURE IS VALID! :)
Same result are for minified and non-minified shim, seemingly the shim is doing something right as the keyimport is working fine.
Thanks again for the library! Npm currently has v0.1.3, which throws these errors on install:
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated [email protected]: please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js
npm WARN deprecated [email protected]: This module relies on Node.js's internals and will break at some point. Do not use it, and update to [email protected].
These should be resolved now that #27 is in. Do you mind promoting a new patch version?
Can you add PBKDF2 algorithm into webcrypto-shim for Internet Explorer 11 and other legacy browsers?
I'm know about asmCrypto, node-forge and similar solutions.
It would be useful to do WebCrypto-style PBKDF2, based on native browser SHA hash implementation to crossbrowser support.
This work on other browsers, but in IE11 with this shim Unsupported Exception is thrown. The importing of a key is working so I know I imported the shim correctly.
window.crypto.subtle.unwrapKey(
"raw",
wrappedKey,
derivedKey,
{ "name": "AES-KW", iv: iv },
{ "name": "AES-CBC", iv: iv },
false,
["decrypt"]
)
I'm trying to use this package to fix Safari's webcrypto but getting
Unsupported algorithm 'hmac'
I've included asymcrypto and elliptic in my html:
<script src="%PUBLIC_URL%/webcrypto.shim.js"></script>
<script src="%PUBLIC_URL%/asmcrypto.min.js"></script>
<script src="%PUBLIC_URL%/elliptic.min.js"></script>
Any advice here?
How is this project related to asmwebcrypto? If I use this I don't need the other? I know the asm lib can be used e.g. to do a pbkdf2 on MS Edge because it does not support this yet. If I now use this shim for IE11 would I still need the other lib for key derivation or? Could you please explain the differencea between the two projects and im what cases I should use one or the other?
I would suggest that in order to verify the compatibility of the library with the various trargetted browsers and in order to keep track of various code quality indicator you could implement integration with Saucelabs and Codeclimate
i'm thinking this while evaluating the validity of the webcrypto-shim for the integration in openpgp.js (openpgpjs/openpgpjs#428), and i've right know implemented what i'm suggesting to you for the https://github.com/indutny/elliptic project: indutny/elliptic#80
It would be great if you could do the same!
Don't see alot of activity and i have a PR that is a week old with no comments or nothing. Is this repo being maintained?
If I use webCrypto-shim to generate a key pair with algorithm name "RSASSA-PKCS1-v1_5" and extractable = false, I get a keypair back where both the public and private key has the extractable flag set to false.
As I understand the standard https://www.w3.org/TR/WebCryptoAPI/#rsassa-pkcs1-operations, the public key should always have extractable = true, and that is also what happens on Chrome.
If I am right, I guess the only change that has to be made, is to change line 363 in the latest version of webcrypto-shim.js
from
_subtle.importKey( 'jwk', keys[0], ka, kx, keys[0].key_ops ),
to
_subtle.importKey( 'jwk', keys[0], ka, true, keys[0].key_ops ),
Regards,
Øyvind ([email protected])
Hi there,
Firstly, thank you for taking the time to creating this library! It really does make a lot of headaches go away :)
I have a question about using it in conjunction with IndexedDB (testing done in IE11), which seems not to be able to store the underlying Key
instances (the _key
field in the custom CryptoKey
definition). That makes for a problem when reading back the stored keys from IndexedDB, as the connection to the original Key
instance is lost along the way, and the keys can no longer be used with the Web Crypto API.
Can you say anything about if it would be possible to support this? I would be more than happy to work on a PR for this, but I'm a bit at a loss for where to start.
Best,
Mikkel
PS: I've tried (naively) to change the definition of the _key
property on the custom CryptoKey
prototype to be enumerable:
_key: {
value: key,
enumerable: true
},
, which fixes my issue, but I'm not sure if doing so would break anything else. The test suite still passes (in Chrome) after this change, but as that part of the code is not executed in Chrome, I'm not sure about any possible ramifications.
Chrome added this security restriction which causes the native Crypto to fail over non-SSL (or localhost) request.
As seen here
Since your library does nothing in chrome (since it supports the native library) my question is:
thanks
Would it be possible to support generating/importing/exporting RSA-OAEP with SHA-384 for the hashing? I am happy to make a PR if you think it would be possible.
Thank you very much, it fixes this shamed safari, however I can't still sign my data.
.sign(<Algorithm>{
name: 'RSASSA-PKCS1-v1_5'
}, privateKey, arrayBuffer)
.then((buffer) => convertArrayBufferToBase64(buffer))
.catch(handleError);
Error: NotSupportedError: DOM Exception 9
Seems like Safari can't use 'RSASSA-PKCS1-v1_5'
PS Can you add 'RSA-PSS' algorithm, please?
When using this cool shim with package managers, it would be nice with a minified version included: webcrypto-shim.min.js
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
So im aware that RSASSA-PKCS1-v1_5 signing with SHA-512 isnt supported but I'm just wondering what needs to go into getting it to work. Is there a reason why it isn't support on this and many other shims and polyfills?
Hi,
I'm trying to use this shim so that I have access to window.crypto.subtle
in an up-to-date version of chrome, but that is served from a non-https origin (i.e. a deployed development environment). Is this possible?
It looks like I am able to load the code:
import('//jspm.dev/webcrypto-shim').then(mdl => console.log(mdl))
But in my chrome console, after doing that I still don't have access to the window.crypto.subtle
object. I know that the reason that I DON'T have the object on my non-https environment is that Chrome explicitly prevents it. I was hoping I could use this shim in such an environment.
Is that possible?
I've been having issues implementing the crypto api for IE11 using RSA-OAEP encryption. After some pain, I discovered with the help of this stack overflow post, https://stackoverflow.com/questions/33047314/public-key-encryption-in-internet-explorer-11, that with IE11 you need to specify a hash in the AlgorithmIdentifier
, which is not in the spec (https://www.w3.org/TR/WebCryptoAPI/#rsa-oaep-operations).
Is this something that:
I'm happy to help with documentation if PRs are welcome.
Cheers
Hey,
I'm trying to include this into a library which I bundle via webpack, but the issue is that this module relies on being run in the global scope, such that this
refers to window
. It would be great to have a way such that it actually refers to window
instead.
Can you make a new npm release? The version currently on npm doesn't work with webpack.
Thank you!
The private key created by IE browser is not in PKCS8 format, but in PKCS#1 format. Is there any way to create a private key in PKCsS8 format?
I use browserstack to test my website and I found out that your polyfill is not working for Android 4.4 with Chrome 63. It returns at
webcrypto-shim/webcrypto-shim.js
Line 28 in c11ecbb
This is the project: emergency-contacts
First of all, many thanks for this library and I really appreciate it.
Currently i encounter some issue of verify and sign, the same code succeed in Chrome and Safari, but fails in IE 11.
I check this table, it shows it works (https://vibornoff.github.io/webcrypto-examples/index.html)
I want to know is it because IE 11 has some special requirement on key format, or some other reason
Here are sample code:
I use two sample keys to test
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC33Wtqlp34gK/H
LcB7ERyjuZcUfAWYYc//LUXs7eHAlZo8WJf9p781aDUfrw2GkwzSjhF+1nXXTxJG
DDmCPWMWc27iEiz3ezU2RL22fcGAaubkrOQZ39Pwi6JxolcXAYWwWeZaa54rxI/h
e+bATOasjv+NaUbqGhnW2VvlDllq3yCK54j/3SIg5sl33PbQat1CPH3nRfMTizkp
IRvgAItFPbzdujAK9fNvcIHzCLuxoq6987xPIcb+ldFZQ07qdh7jmJsJWyuoawMM
2IKhXuEeocnp0wGMIiymruNTa15bbaeVc+pbZFO7ikYLPuADcqBGm+KfgDiJ8VuN
P19fZuf1AgMBAAECggEAUU3EFhoMOLsO/5CnsMPcWjnTKOe+wadfBoPKi/6U+Ugu
L8ktTKlE0CUIeL47yOp1nRXdfqzu5wq8FeWJ+KGUk3Tv72ACKl19JkY3bd8mFdcv
yqb5JsfnPFNCveT/hdjSeS0Hw6wbAVemGBtl6lsXFe8V6j5HcXWhP3RWQm+Z8rt/
6LRf+2CVyzaJ3OCMZ+3u5RA2+b2MdtSLNKEgVTvur4BgJt7Mf7NrcuB65El/oXmq
u5YcIr2MH/rlZTWVkq2Zr0ck7LfBpJkj11L6UyY2h9pceleoAgl9p54EjhtPud46
UHIQt6eXst33Kx5q4zKUzcdO0tbjJj9BOZfh5GsZgQKBgQDiT2KZNEh0+PnVwZuY
3KoHZxRFHIw7vD0lyEaQdgDAfgUd/U7LN/hMRBFoJRHD4EWJtMAPS3Bkd1X7thte
LtdTfMLSvJsUbiqUQHENY62CNsvd1llC29QQWmqLObKJXubb9JhISZm7qKBK53yi
dPVUS7krn7L/rykdi+3amim06QKBgQDP/IPV04+4HIt9Rm9ciNhX5Y2q3tOGwKD9
AEfurwp2wdvMpEoCE7B9UBW69ZtYibqaaCOHw52/sUVesyLl9Ber4Bi0X0uJNtXA
4HwUMW1NHS7kXey0Cblap2XpHPBKkeeKTmIkXmTxGHtvoO+Flv38XiPLytrqFWGZ
eq7yurxjLQKBgQC/Xvf2q8KVv7CstGKaWgch6WW3p5NiNCTVHU2mfVLXc/lpyblm
mXbLL0g09BvYsn67GvDKPjXVjyBTkUQFWcDWJYst3zWYiixRX0j6VI71rNaqSccD
hZcHGR49i1XRWkIIQAbCIhLxIIAjtyqqyhJm7P2xyQL5uaogBSLmlzSreQKBgAKZ
YkBi03H2kVuwbKXYY/O9P6b5/+S4NYrT3RJDh7ryMz/8cZxTCKqYPJ1Ignd5ySYy
1PbWX/tMSNSlInODOGSCeWyPoE8Hq2YsqABMmdQT4EkkT1f0oydZ3jEqlmooJp+Y
2SshLtvAdZJwjW269FOaDZJ3Z4LzX3Pej58i7EXFAoGADsupd90wI+weAgGE0Pd5
gnuZwwASkpBjz4sH5I6aO59CNZIA3yuoEmjSBCJu7glExt/QoimXwI2tJwZJew4Y
3r57ULcbJbpe0uwvFT6mVt6b6vHvKCpV8nZPHKJ2r86gSOPNBWZvSmSSUPrOBPWf
PKLBxAFL8pNmAAwCS3EnMxM=
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt91rapad+ICvxy3AexEc
o7mXFHwFmGHP/y1F7O3hwJWaPFiX/ae/NWg1H68NhpMM0o4RftZ1108SRgw5gj1j
FnNu4hIs93s1NkS9tn3BgGrm5KzkGd/T8IuicaJXFwGFsFnmWmueK8SP4XvmwEzm
rI7/jWlG6hoZ1tlb5Q5Zat8giueI/90iIObJd9z20GrdQjx950XzE4s5KSEb4ACL
RT283bowCvXzb3CB8wi7saKuvfO8TyHG/pXRWUNO6nYe45ibCVsrqGsDDNiCoV7h
HqHJ6dMBjCIspq7jU2teW22nlXPqW2RTu4pGCz7gA3KgRpvin4A4ifFbjT9fX2bn
9QIDAQAB
-----END PUBLIC KEY-----
The sign and verify process
const dataString = 'Hello world!';
const dataBuffer = encode(dataString);
const rsaParams = {
name: 'RSASSA-PKCS1-v1_5',
hash: 'SHA-256',
};
const privateKeyData = pemToBinary(privateKeyRaw);
crypto.subtle.importKey('pkcs8', privateKeyData, rsaParams, false, ['sign']).then((privateKey) => {
// The next step will throw error in IE
crypto.subtle.sign('RSASSA-PKCS1-v1_5', privateKey, dataBuffer).then((signature) => {
const sign = window.btoa(decode(signature));
console.log(sign); // the sign value should be same as below
});
});
const sign = 'kPEpAVSxYPkGAP82WM2sJkxo4rvo6NRWvM/ehPwm3Iu4PejJAS10d/dtOF4LHOHKNcv+ypgybiLyJpafdbVy9kSltBMSIm87hFRDRoqWvuhSXzY4pLDMfiOVDrQufsya3CYRWoF7dwJuZeU170iXaMJiIEWyKxFLfpDWCUPdMcV+qpOf69NtvQHFRmH1E7s8NRnXxdl0t7qu0C2kLR5LlQnGYVezoi7qBUjVtxs1pgfk8U8hdO2l8ZgWo4dnA2HW7uKjnRKGzcSKNPST9i84Yu+BCdRuRPVwabWoHFf3CS/FZc2zIg4ZUK3npzYNysOUNxqEQm8cTOpmKLTvn3fyfw=='
const signature = encode(window.atob(sign));
const publicKeyData = pemToBinary(publicKeyRaw);
crypto.subtle.importKey('spki', publicKeyData, rsaParams, false, ['verify']).then((publicKey) => {
// The next step will throw error in IE
crypto.subtle.verify('RSASSA-PKCS1-v1_5', publicKey, signature, dataBuffer).then((verified) => {
console.log(verified); // verified should be true
});
});
function encode(str) {
const bufferView = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
bufferView[i] = str.charCodeAt(i);
}
return bufferView;
}
function decode(buffer) {
const bufferView = new Uint8Array(buffer);
let str = '';
for (let i = 0; i < bufferView.length; i++) {
str += String.fromCharCode(bufferView[i]);
}
return str;
}
function pemToBinary(pem) {
const lines = pem.split('\n');
let pemContents = '';
for (let i = 1; i < lines.length - 1; i++) {
pemContents += lines[i].trim();
}
const pemDer = window.atob(pemContents);
return encode(pemDer);
}
When passing an instance of DataView
as the data argument of encrypt
in Internet Explorer, an error "Error: Invalid argument" is thrown.
Example snippet:
crypto.subtle.generateKey( { name: 'AES-GCM', length: 256 }, true, [ 'encrypt', 'decrypt' ] )
.then( function ( key ) {
return crypto.subtle.encrypt( { name: 'AES-GCM', iv: new Uint8Array(12), tagLength: 128 }, key, new DataView(new Uint8Array(16).buffer) )
}).then( function() { console.log('Done'); }).catch(function( err ) { console.log('Error', err); });
This works in other browsers, and is at least documented by TypeScript built-in DOM types as a supported type for the data
argument (source). I assume this is based on specifications, though I've not yet tracked those down.
Have you considered publishing this shim to npm? I am working on project that uses npm for browser dependencies, and I would like to include your shim as a dependency.
I've included a link to another project that ended up publishing to npm, as they discuss the reasons for publishing to npm better than I could.
https://github.com/coolaj86/unibabel-js/issues/7
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.