15

I have read that, generally, some implementations of SecureRandom may produce true random numbers.

In particular, the Android docs say

instances of this class will generate an initial seed using an internal entropy source, such as /dev/urandom

but does that mean it will produce true random numbers (i.e., rather than pseudo-random numbers)?

And if I use SecureRandom in Android in this manner...

SecureRandom sr = new SecureRandom();

...will I get a truly random output whenever I call sr.nextBoolean()?

Or is the output likely to be more (or less?) random if I, instead, obtain output by doing this each time: new SecureRandom().nextBoolean()?

frogatto
  • 28,539
  • 11
  • 83
  • 129
ban-geoengineering
  • 18,324
  • 27
  • 171
  • 253
  • 1
    This is not *necessarily* true as some Android devices do not have the hardware to generate a *true* random number. As for whether devices *with* that hardware will use it, I would not assume so, though the Linux kernel might load a module that gets true random numbers from such hardware. – nanofarad Sep 12 '14 at 21:33
  • 1
    AFAIK all implementations use different forms or algorithmic hashing. While having good mathematical properties, they are not truly random. – Peter Lawrey Sep 12 '14 at 21:35
  • 1
    From [Android Developer's Blog](http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html): *"We have now determined that applications which use the Java Cryptography Architecture (JCA) for key generation, signing, or random number generation may not receive cryptographically strong values on Android devices due to improper initialization of the underlying PRNG..."*. After that, I believe AOSP switch to OpenSSL's generator. The change occured at [Jelly Bean](http://android-developers.blogspot.com/2013/02/security-enhancements-in-jelly-bean.html). – jww Sep 13 '14 at 01:23
  • @ban-geoengineering - I have code to read Android's sensors using JNI and then seed a random number generator (like OpenSSL or Crypto++). You could use it to do the same, or use it to seed a Java HMAC/SHA-1 generator. The "meat and potatoes" source file is on Pastebin at [Android/Crypto++ PRNG auto-seeded from sensors (by JWW)](http://pastebin.com/0DtQ77MA). I hope to upload the Eclipse project to the [Crypto++ wiki](http://www.cryptopp.com/wiki/Main_Page) soon (the wiki is having trouble at the moment due to a configuration change). – jww Sep 13 '14 at 01:40
  • Hang on. /dev/urandom is only used to produce the initial seed. After that, everything is algorithmic. SecureRandom is *required* to 'provide a cryptographically strong random number generator (RNG)'. – user207421 Sep 13 '14 at 01:57

3 Answers3

5

"True" and "pseudorandom" random numbers mean a lot of different things to different people. It's best to avoid those.

/dev/urandom got a bad rep because people do not understand the differences between it and /dev/random (much, much less difference than you would expect).

If you're asking whether seeding by /dev/urandom might compromise the fitness of SecureRandom to use it for cryptographic purposes, the answer is a resounding "no".

If you've got some time you might want to read my essay about the whole issue.

frogatto
  • 28,539
  • 11
  • 83
  • 129
Thomas
  • 356
  • 4
  • 11
1

According to the Android Developer Docs:

(SecureRandom) complies with the statistical random number generator tests specified in FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1

However, the same caveats apply to Android as to Java:

Many SecureRandom implementations are in the form of a pseudo-random number generator (PRNG), which means they use a deterministic algorithm to produce a pseudo-random sequence from a true random seed. Other implementations may produce true random numbers, and yet others may use a combination of both techniques.

So, the short answer is: it depends on the implementation, but if you're ok with FIPS 140-2, then SecureRandom is legally sufficient for your purposes.

david.barkhuizen
  • 5,239
  • 4
  • 36
  • 38
0

The key answer is that /dev/urandom, as defined by the linux kernel, is guaranteed not to block. The emphasis being upon not stalling the user while sufficient entropy is generated. If the android docs say they are using /dev/urandom to initialize, AND there is insufficient entropy in the kernel to supply random numbers, the kernel will fall back to a pseudo-random algorithm.

Per the kernel documentation, /dev/urandom is considered sufficient for almost all purposes except "long lived [encryption] keys". Given the description of your intended use, I suspect android SecureRandom will prove to be random enough for your purposes.

frogatto
  • 28,539
  • 11
  • 83
  • 129
caskey
  • 12,305
  • 2
  • 26
  • 27
  • 1
    Android is kind of a distinct beast. It has `/dev/urandom`, but I don't believe Android's `SecureRandom` and `SecureRandomSpi` were using it. Instead, the seed was really weak - it was essentially system properties (like serial number, baseband version), time (milli and nano seconds) and the string *"All Your Randomness Are Belong To Us"*. Check out [EntropyService.java](https://code.google.com/p/android-source-browsing/source/browse/services/java/com/android/server/EntropyService.java?repo=platform--frameworks--base&name=b8cba95f&r=6907891b1f2d706fa2bd6c40b986f73e5666e00e). – jww Sep 13 '14 at 01:32