simplify random.js
This commit is contained in:
parent
3df1d849b3
commit
b088f005da
|
@ -54,7 +54,7 @@ function getPkcs1Padding(length) {
|
|||
let result = '';
|
||||
let randomByte;
|
||||
while (result.length < length) {
|
||||
randomByte = random.getSecureRandomOctet();
|
||||
randomByte = random.getRandomBytes(1)[0];
|
||||
if (randomByte !== 0) {
|
||||
result += String.fromCharCode(randomByte);
|
||||
}
|
||||
|
|
|
@ -38,49 +38,7 @@ export default {
|
|||
* @return {Uint8Array} Random byte array
|
||||
*/
|
||||
getRandomBytes: function(length) {
|
||||
const result = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
result[i] = this.getSecureRandomOctet();
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a secure random number in the specified range
|
||||
* @param {Integer} from Min of the random number
|
||||
* @param {Integer} to Max of the random number (max 32bit)
|
||||
* @return {Integer} A secure random number
|
||||
*/
|
||||
getSecureRandom: function(from, to) {
|
||||
let randUint = this.getSecureRandomUint();
|
||||
const bits = ((to - from)).toString(2).length;
|
||||
while ((randUint & ((2 ** bits) - 1)) > (to - from)) {
|
||||
randUint = this.getSecureRandomUint();
|
||||
}
|
||||
return from + (Math.abs(randUint & ((2 ** bits) - 1)));
|
||||
},
|
||||
|
||||
getSecureRandomOctet: function() {
|
||||
const buf = new Uint8Array(1);
|
||||
this.getRandomValues(buf);
|
||||
return buf[0];
|
||||
},
|
||||
|
||||
getSecureRandomUint: function() {
|
||||
const buf = new Uint8Array(4);
|
||||
const dv = new DataView(buf.buffer);
|
||||
this.getRandomValues(buf);
|
||||
return dv.getUint32(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper routine which calls platform specific crypto random generator
|
||||
* @param {Uint8Array} buf
|
||||
*/
|
||||
getRandomValues: function(buf) {
|
||||
if (!(buf instanceof Uint8Array)) {
|
||||
throw new Error('Invalid type: buf not an Uint8Array');
|
||||
}
|
||||
const buf = new Uint8Array(length);
|
||||
if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {
|
||||
window.crypto.getRandomValues(buf);
|
||||
} else if (typeof window !== 'undefined' && typeof window.msCrypto === 'object' && typeof window.msCrypto.getRandomValues === 'function') {
|
||||
|
@ -126,15 +84,17 @@ export default {
|
|||
function RandomBuffer() {
|
||||
this.buffer = null;
|
||||
this.size = null;
|
||||
this.callback = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize buffer
|
||||
* @param {Integer} size size of buffer
|
||||
*/
|
||||
RandomBuffer.prototype.init = function(size) {
|
||||
RandomBuffer.prototype.init = function(size, callback) {
|
||||
this.buffer = new Uint8Array(size);
|
||||
this.size = 0;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,7 +79,7 @@ SymEncryptedAEADProtected.prototype.decrypt = function (sessionKeyAlgorithm, key
|
|||
* @return {Promise<undefined>} Nothing is returned
|
||||
*/
|
||||
SymEncryptedAEADProtected.prototype.encrypt = function (sessionKeyAlgorithm, key) {
|
||||
this.iv = crypto.random.getRandomValues(new Uint8Array(IV_LEN)); // generate new random IV
|
||||
this.iv = crypto.random.getRandomBytes(IV_LEN); // generate new random IV
|
||||
return crypto.gcm.encrypt(sessionKeyAlgorithm, this.packets.write(), key, this.iv).then(encrypted => {
|
||||
this.encrypted = encrypted;
|
||||
});
|
||||
|
|
|
@ -20,7 +20,6 @@ import crypto from '../crypto';
|
|||
import packet from '../packet';
|
||||
|
||||
const INITIAL_RANDOM_SEED = 50000; // random bytes seeded to worker
|
||||
const RANDOM_SEED_REQUEST = 20000; // random bytes seeded after worker request
|
||||
|
||||
/**
|
||||
* Initializes a new proxy and loads the web worker
|
||||
|
@ -75,7 +74,7 @@ AsyncProxy.prototype.onMessage = function(event) {
|
|||
delete this.tasks[msg.id];
|
||||
break;
|
||||
case 'request-seed':
|
||||
this.seedRandom(RANDOM_SEED_REQUEST);
|
||||
this.seedRandom(msg.amount);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown Worker Event.');
|
||||
|
@ -87,24 +86,10 @@ AsyncProxy.prototype.onMessage = function(event) {
|
|||
* @param {Integer} size Number of bytes to send
|
||||
*/
|
||||
AsyncProxy.prototype.seedRandom = function(size) {
|
||||
const buf = this.getRandomBuffer(size);
|
||||
const buf = crypto.random.getRandomBytes(size);
|
||||
this.worker.postMessage({ event:'seed-random', buf }, util.getTransferables(buf));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Uint8Array with random numbers
|
||||
* @param {Integer} size Length of buffer
|
||||
* @return {Uint8Array}
|
||||
*/
|
||||
AsyncProxy.prototype.getRandomBuffer = function(size) {
|
||||
if (!size) {
|
||||
return null;
|
||||
}
|
||||
const buf = new Uint8Array(size);
|
||||
crypto.random.getRandomValues(buf);
|
||||
return buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* Terminates the worker
|
||||
*/
|
||||
|
|
|
@ -24,10 +24,29 @@ self.window = {}; // to make UMD bundles work
|
|||
importScripts('openpgp.js');
|
||||
var openpgp = window.openpgp;
|
||||
|
||||
var randomQueue = [];
|
||||
var randomRequested = false;
|
||||
var MIN_SIZE_RANDOM_BUFFER = 40000;
|
||||
var MAX_SIZE_RANDOM_BUFFER = 60000;
|
||||
var MIN_SIZE_RANDOM_REQUEST = 20000;
|
||||
|
||||
openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
|
||||
/**
|
||||
* Handle random buffer exhaustion by requesting more random bytes from the main window
|
||||
* @return {Promise<Object>} Empty promise whose resolution indicates that the buffer has been refilled
|
||||
*/
|
||||
function randomCallback() {
|
||||
|
||||
if (!randomRequested) {
|
||||
self.postMessage({ event: 'request-seed', amount: MAX_SIZE_RANDOM_BUFFER });
|
||||
}
|
||||
randomRequested = true;
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
randomQueue.push(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER, randomCallback);
|
||||
|
||||
/**
|
||||
* Handle messages from the main window.
|
||||
|
@ -43,6 +62,13 @@ self.onmessage = function(event) {
|
|||
|
||||
case 'seed-random':
|
||||
seedRandom(msg.buf);
|
||||
|
||||
var queueCopy = randomQueue;
|
||||
randomQueue = [];
|
||||
for (var i = 0; i < queueCopy.length; i++) {
|
||||
queueCopy[i]();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -99,8 +125,8 @@ function delegate(id, method, options) {
|
|||
* @param {Object} event Contains event type and data
|
||||
*/
|
||||
function response(event) {
|
||||
if (openpgp.crypto.random.randomBuffer.size < MIN_SIZE_RANDOM_BUFFER) {
|
||||
self.postMessage({ event: 'request-seed' });
|
||||
if (!randomRequested && openpgp.crypto.random.randomBuffer.size < MIN_SIZE_RANDOM_BUFFER) {
|
||||
self.postMessage({ event: 'request-seed', amount: MIN_SIZE_RANDOM_REQUEST });
|
||||
}
|
||||
self.postMessage(event, openpgp.util.getTransferables(event.data));
|
||||
}
|
||||
|
|
|
@ -309,7 +309,7 @@ describe('API functional testing', function() {
|
|||
if(algo.substr(0,3) === 'aes') {
|
||||
it(algo, function() {
|
||||
const key = crypto.generateSessionKey(algo);
|
||||
const iv = crypto.random.getRandomValues(new Uint8Array(crypto.gcm.ivLength));
|
||||
const iv = crypto.random.getRandomBytes(crypto.gcm.ivLength);
|
||||
|
||||
return crypto.gcm.encrypt(
|
||||
algo, util.str_to_Uint8Array(plaintext), key, iv
|
||||
|
|
Loading…
Reference in New Issue
Block a user