I'm trying to generate keypairs in a React Native project. The key pair generation tool relies on the crypto module's random byte generation, which produces a buffer of a specified lengths with random byte values.
In order to use the crypto module within React Native, it has to be browserified, and the browserified random number generator looks like this:
Here's the key component:
var crypto = global.crypto || global.msCrypto
if (crypto && crypto.getRandomValues) {
module.exports = randomBytes
} else {
module.exports = oldBrowser
}
Indeed, when debugging the application with Chrome, everything works fine, but when running it on iOS's JavaScriptCore engine, the oldBrowser method gets called instead, throwing the following error:
secure random number generation not supported by this browser use chrome, FireFox or Internet Explorer 11
Thus I'm trying to find a replacement for the random bytes generation. One module I found is this one:
It uses the device's native libraries to generate a random number, and exposes it to React Native through their Obj-C/JS interface. It should be noted that this method only works on iOS, and the library's author doesn't have an Android solution yet, but that's an issue for another time.
This method works, in that it can generate random bytes, but it has one major drawback. React only supports asynchronous interfacing between Objective-C and JavaScript, which means that this method returns its results asynchronously. The original randomBytes method is synchronous, and pretty much every SDK out there that relies on it uses it synchronously. So if we were to go with the async version, all the SDKs would have to be rewritten for it, including all dependencies that rely on methods that used to be synchronous and now would no longer be.
Thus I'm trying to find a way to make the asynchronous native random number generator work synchronously. There are several node packages that do that, the most prominent one of them being deasync, but deasync relies on some core Node modules that cannot be browserified, so the synchronous version doesn't work.
Alternatively, I've tried wrapping it in a method that would set a semaphore, call the async generator, and wait in a while loop for the semaphore's value to change. That attempt failed because the while loop was blocking the callback from ever executing. Here's an approximation of my attempts, where the call to the async method has been replaced with a setTimeout, and the random number to be returned is a four, as determined by a fair dice roll.
function testSynchronicity() {
var isDone = false;
setTimeout(function() {
isDone = true;
}, 1000); // set isDone to true after a second
while (!isDone) {
// do nothing
}
return 4;
};
As this wasn't working, I figured I would try a completely different random number generator entirely, without the native-code-relying react-native-randombytes module and went with this one for JavaScript:
It worked fine within Node itself, but after browserifying it and trying to run the first example within React Native, it threw an error saying that the main object was not a constructor. Here's what the example looks like:
var RNG = require('./rng_react'); // rng_react is rng-js browserified
var rng = new RNG();
var randomValue = rng.random(0, 255, false);
So at this point, I'm at a bit of a loss, and would appreciate any help. Thanks!
Aucun commentaire:
Enregistrer un commentaire