Closed ianopolous closed 8 years ago
I'm guessing there's either a native method we are missing for SecureRNG, or we need to set a magic system property pointing to a class that implements secure RNG.
@ianopolous Can you submit a minimal Java class with a public static void main
that exhibits this issue?
The system property is "securerandom.strongAlgorithms" It's of the following format: / * Entries are alg:prov separated by , * Allow for prepended/appended whitespace between entries. * Capture groups: * 1 - alg * 2 - :prov (optional) * 3 - prov (optional) * 4 - ,nextEntry (optional) * 5 - nextEntry (optional) / private static Pattern pattern = Pattern.compile( "\s([\S&&[^:,]])(\:([\S&&[^,]]))?\s(\,(.))?");
This should be sufficient. My code calls it deep in Peergos, but this is equivalent:
import java.security.*;
class test {
public static void main(String[] args) {
java.security.SecureRandom.getInstanceStrong();
}
}
Interesting. This code works under Node on my Mac because it simply reads /dev/urandom
. :)
The system property contains the following data:
#
# A list of known strong SecureRandom implementations.
#
# To help guide applications in selecting a suitable strong
# java.security.SecureRandom implementation, Java distributions should
# indicate a list of known strong implementations using the property.
#
# This is a comma-separated list of algorithm and/or algorithm:provider
# entries.
#
securerandom.strongAlgorithms=NativePRNGBlocking:SUN
It looks like to do this the "proper way", we'd have to have a DoppioSecurityProvider
that provides RNG for the browser, and register that with the JVM.
I'm making a small change right now to move doppio.jar
generation and classes from the doppio_jcl repository into this repository, which will make it easy to add custom Doppio classes like these in the future.
The best cross browser (and node) code I'm aware of for finding a secure random source is from the end of: https://github.com/dchest/tweetnacl-js/blob/master/nacl.js (public domain)
// Initialize PRNG if environment provides CSPRNG.
// If not, methods calling randombytes will throw.
var crypto;
if (typeof window !== 'undefined') {
// Browser.
if (window.crypto && window.crypto.getRandomValues) {
crypto = window.crypto; // Standard
} else if (window.msCrypto && window.msCrypto.getRandomValues) {
crypto = window.msCrypto; // Internet Explorer 11+
}
if (crypto) {
nacl.setPRNG(function(x, n) {
var i, v = new Uint8Array(n);
crypto.getRandomValues(v);
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
});
}
} else if (typeof require !== 'undefined') {
// Node.js.
crypto = require('crypto');
if (crypto) {
nacl.setPRNG(function(x, n) {
var i, v = crypto.randomBytes(n);
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
});
}
}
Committed in https://github.com/plasma-umass/doppio/commit/f23922ab733cc831943bd6b3808ab3afc0982a46, but the CI build is broken for some unknown reason (it stalls on running Java to generate unit test data).
Keeping this open until that gets cleared up...
Alright, my change works!
Small note: crypto
is not available in WebWorkers in Firefox until Firefox 48 hits, causing Travis-CI failures in that browser. This is outside of our control, so I am marking this as "closed".
Running code that calls java.security.SecureRandom.getInstanceStrong() throws "No strong SecureRandom impls available: NativePRNGBlocking:SUN"