Merge pull request #296 from bartbutler/ie11_keygen

Support for crypto API keygen in IE11 on Windows 7 and 8
This commit is contained in:
Tankred Hase 2015-06-09 15:43:40 +02:00
commit a12d2ee27e
2 changed files with 47 additions and 20 deletions

View File

@ -145,7 +145,17 @@ function RSA() {
var Euint8 = new Uint8Array(Euint32.buffer); // get bytes of exponent
var keyGenOpt;
if (window.crypto.subtle) {
var keys;
if (window.crypto && window.crypto.webkitSubtle) {
// outdated spec implemented by Webkit
keyGenOpt = {
name: 'RSA-OAEP',
modulusLength: B, // the specified keysize in bits
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
};
keys = webCrypto.generateKey(keyGenOpt, true, ['encrypt', 'decrypt']);
}
else {
// current standard spec
keyGenOpt = {
name: 'RSASSA-PKCS1-v1_5',
@ -155,29 +165,30 @@ function RSA() {
name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
}
};
return webCrypto.generateKey(keyGenOpt, true, ['sign', 'verify']).then(exportKey).then(decodeKey);
} else if (window.crypto.webkitSubtle) {
// outdated spec implemented by Webkit
keyGenOpt = {
name: 'RSA-OAEP',
modulusLength: B, // the specified keysize in bits
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
};
return webCrypto.generateKey(keyGenOpt, true, ['encrypt', 'decrypt']).then(exportKey).then(function(key) {
if (key instanceof ArrayBuffer) {
// parse raw ArrayBuffer bytes to jwk/json (WebKit/Safari quirk)
return decodeKey(JSON.parse(String.fromCharCode.apply(null, new Uint8Array(key))));
}
return decodeKey(key);
});
keys = webCrypto.generateKey(keyGenOpt, true, ['sign', 'verify']);
if (!(keys instanceof Promise)) { // IE11 KeyOperation
keys = convertKeyOperation(keys, 'Error generating RSA key pair.');
}
}
return keys.then(exportKey).then(function(key) {
if (key instanceof ArrayBuffer) {
// parse raw ArrayBuffer bytes to jwk/json (WebKit/Safari/IE11 quirk)
return decodeKey(JSON.parse(String.fromCharCode.apply(null, new Uint8Array(key))));
}
return decodeKey(key);
});
}
function exportKey(keypair) {
// export the generated keys as JsonWebKey (JWK)
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
return webCrypto.exportKey('jwk', keypair.privateKey);
var key = webCrypto.exportKey('jwk', keypair.privateKey);
if (!(key instanceof Promise)) { // IE11 KeyOperation
key = convertKeyOperation(key, 'Error exporting RSA key pair.');
}
return key;
}
function decodeKey(jwk) {
@ -199,6 +210,17 @@ function RSA() {
return key;
}
function convertKeyOperation(keyop, errmsg) {
return new Promise(function(resolve, reject) {
keyop.onerror = function (err) {
reject(new Error(errmsg));
}
keyop.oncomplete = function (e) {
resolve(e.target.result);
}
});
}
//
// JS code
//

View File

@ -320,8 +320,13 @@ module.exports = {
return;
}
if (typeof window !== 'undefined' && window.crypto) {
return window.crypto.subtle || window.crypto.webkitSubtle;
if (typeof window !== 'undefined') {
if (window.crypto) {
return window.crypto.subtle || window.crypto.webkitSubtle;
}
if (window.msCrypto) {
return window.msCrypto.subtle;
}
}
}
};