Cleanup RSA and util code
This commit is contained in:
parent
55bd9757e7
commit
4d325ca65c
|
@ -29,6 +29,9 @@
|
|||
"before": true,
|
||||
"beforeEach": true,
|
||||
"after": true,
|
||||
"afterEach": true
|
||||
"afterEach": true,
|
||||
"escape": true,
|
||||
"unescape": true,
|
||||
"asmCrypto": true
|
||||
}
|
||||
}
|
|
@ -24,6 +24,8 @@
|
|||
* @module crypto/public_key/rsa
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var BigInteger = require('./jsbn.js'),
|
||||
util = require('../../util.js'),
|
||||
random = require('../random.js'),
|
||||
|
@ -119,7 +121,7 @@ function RSA() {
|
|||
|
||||
// "empty" RSA key constructor
|
||||
|
||||
function keyObject() {
|
||||
function KeyObject() {
|
||||
this.n = null;
|
||||
this.e = 0;
|
||||
this.ee = null;
|
||||
|
@ -167,8 +169,8 @@ function RSA() {
|
|||
};
|
||||
|
||||
keys = webCrypto.generateKey(keyGenOpt, true, ['sign', 'verify']);
|
||||
if (!(typeof keys.then === 'function')) { // IE11 KeyOperation
|
||||
keys = convertKeyOperation(keys, 'Error generating RSA key pair.');
|
||||
if (typeof keys.then !== 'function') { // IE11 KeyOperation
|
||||
keys = util.promisifyIE11Op(keys, 'Error generating RSA key pair.');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,15 +187,15 @@ function RSA() {
|
|||
// export the generated keys as JsonWebKey (JWK)
|
||||
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
|
||||
var key = webCrypto.exportKey('jwk', keypair.privateKey);
|
||||
if (!(typeof key.then === 'function')) { // IE11 KeyOperation
|
||||
key = convertKeyOperation(key, 'Error exporting RSA key pair.');
|
||||
if (typeof key.then !== 'function') { // IE11 KeyOperation
|
||||
key = util.promisifyIE11Op(key, 'Error exporting RSA key pair.');
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
function decodeKey(jwk) {
|
||||
// map JWK parameters to local BigInteger type system
|
||||
var key = new keyObject();
|
||||
var key = new KeyObject();
|
||||
key.n = toBigInteger(jwk.n);
|
||||
key.ee = new BigInteger(E, 16);
|
||||
key.d = toBigInteger(jwk.d);
|
||||
|
@ -210,23 +212,12 @@ 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
|
||||
//
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
var key = new keyObject();
|
||||
var key = new KeyObject();
|
||||
var rng = new SecureRandom();
|
||||
var qs = B >> 1;
|
||||
key.e = parseInt(E, 16);
|
||||
|
@ -235,13 +226,15 @@ function RSA() {
|
|||
for (;;) {
|
||||
for (;;) {
|
||||
key.p = new BigInteger(B - qs, 1, rng);
|
||||
if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) === 0 && key.p.isProbablePrime(10))
|
||||
if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) === 0 && key.p.isProbablePrime(10)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
key.q = new BigInteger(qs, 1, rng);
|
||||
if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) === 0 && key.q.isProbablePrime(10))
|
||||
if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) === 0 && key.q.isProbablePrime(10)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key.p.compareTo(key.q) <= 0) {
|
||||
var t = key.p;
|
||||
|
@ -270,7 +263,7 @@ function RSA() {
|
|||
this.verify = verify;
|
||||
this.sign = sign;
|
||||
this.generate = generate;
|
||||
this.keyObject = keyObject;
|
||||
this.keyObject = KeyObject;
|
||||
}
|
||||
|
||||
module.exports = RSA;
|
||||
|
|
72
src/util.js
72
src/util.js
|
@ -69,11 +69,14 @@ module.exports = {
|
|||
var i = 0;
|
||||
while (c < e) {
|
||||
h = str.charCodeAt(c++).toString(16);
|
||||
while (h.length < 2) h = "0" + h;
|
||||
while (h.length < 2) {
|
||||
h = "0" + h;
|
||||
}
|
||||
r.push(" " + h);
|
||||
i++;
|
||||
if (i % 32 === 0)
|
||||
if (i % 32 === 0) {
|
||||
r.push("\n ");
|
||||
}
|
||||
}
|
||||
return r.join('');
|
||||
},
|
||||
|
@ -84,15 +87,18 @@ module.exports = {
|
|||
* @return {String} String containing the hexadecimal values
|
||||
*/
|
||||
hexstrdump: function (str) {
|
||||
if (str === null)
|
||||
if (str === null) {
|
||||
return "";
|
||||
}
|
||||
var r = [];
|
||||
var e = str.length;
|
||||
var c = 0;
|
||||
var h;
|
||||
while (c < e) {
|
||||
h = str.charCodeAt(c++).toString(16);
|
||||
while (h.length < 2) h = "0" + h;
|
||||
while (h.length < 2) {
|
||||
h = "0" + h;
|
||||
}
|
||||
r.push("" + h);
|
||||
}
|
||||
return r.join('');
|
||||
|
@ -105,8 +111,9 @@ module.exports = {
|
|||
*/
|
||||
hex2bin: function (hex) {
|
||||
var str = '';
|
||||
for (var i = 0; i < hex.length; i += 2)
|
||||
for (var i = 0; i < hex.length; i += 2) {
|
||||
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
|
||||
}
|
||||
return str;
|
||||
},
|
||||
|
||||
|
@ -122,7 +129,9 @@ module.exports = {
|
|||
var h;
|
||||
while (c < e) {
|
||||
h = str[c++].toString(16);
|
||||
while (h.length < 2) h = "0" + h;
|
||||
while (h.length < 2) {
|
||||
h = "0" + h;
|
||||
}
|
||||
r.push("" + h);
|
||||
}
|
||||
return r.join('');
|
||||
|
@ -189,7 +198,7 @@ module.exports = {
|
|||
str2Uint8Array: function (str) {
|
||||
|
||||
// Uncomment for debugging
|
||||
if(!(typeof str === 'string') && !String.prototype.isPrototypeOf(str)) {
|
||||
if(typeof str !== 'string' && !String.prototype.isPrototypeOf(str)) {
|
||||
throw new Error('str2Uint8Array: Data must be in the form of a string');
|
||||
}
|
||||
|
||||
|
@ -227,7 +236,7 @@ module.exports = {
|
|||
* @param {Array<Uint8array>} Array of Uint8Arrays to concatenate
|
||||
* @return {Uint8array} Concatenated array
|
||||
*/
|
||||
concatUint8Array: function (arrays) {
|
||||
concatUint8Array: function (arrays) {
|
||||
|
||||
var totalLength = 0;
|
||||
arrays.forEach(function (element) {
|
||||
|
@ -248,7 +257,7 @@ module.exports = {
|
|||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Deep copy Uint8Array
|
||||
|
@ -342,8 +351,9 @@ module.exports = {
|
|||
|
||||
getLeftNBits: function (string, bitcount) {
|
||||
var rest = bitcount % 8;
|
||||
if (rest === 0)
|
||||
if (rest === 0) {
|
||||
return string.substring(0, bitcount / 8);
|
||||
}
|
||||
var bytes = (bitcount - rest) / 8 + 1;
|
||||
var result = string.substring(0, bytes);
|
||||
return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF);
|
||||
|
@ -357,17 +367,18 @@ module.exports = {
|
|||
* @return {String} Resulting string.
|
||||
*/
|
||||
shiftRight: function (value, bitcount) {
|
||||
var temp = util.str2bin(value);
|
||||
var temp = this.str2bin(value);
|
||||
if (bitcount % 8 !== 0) {
|
||||
for (var i = temp.length - 1; i >= 0; i--) {
|
||||
temp[i] >>= bitcount % 8;
|
||||
if (i > 0)
|
||||
if (i > 0) {
|
||||
temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
return util.bin2str(temp);
|
||||
return this.bin2str(temp);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -413,5 +424,40 @@ module.exports = {
|
|||
return window.msCrypto.subtle;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Wraps a generic synchronous function in an ES6 Promise.
|
||||
* @param {Function} fn The function to be wrapped
|
||||
* @return {Function} The function wrapped in a Promise
|
||||
*/
|
||||
promisify: function(fn) {
|
||||
return function() {
|
||||
var args = arguments;
|
||||
return new Promise(function(resolve) {
|
||||
var result = fn.apply(null, args);
|
||||
resolve(result);
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts an IE11 web crypro api result to a promise.
|
||||
* This is required since IE11 implements an old version of the
|
||||
* Web Crypto specification that does not use promises.
|
||||
* @param {Object} cryptoOp The return value of an IE11 web cryptro api call
|
||||
* @param {String} errmsg An error message for a specific operation
|
||||
* @return {Promise} The resulting Promise
|
||||
*/
|
||||
promisifyIE11Op: function(cryptoOp, errmsg) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
cryptoOp.onerror = function () {
|
||||
reject(new Error(errmsg));
|
||||
};
|
||||
cryptoOp.oncomplete = function (e) {
|
||||
resolve(e.target.result);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user