Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I ported GnuPG to Javascript using Emscripten (not released yet). Now I need a good replacement for /dev/random//dev/urandom. New browsers support window.crypto.getRandomValues() but for older browsers I need something else. I was thinking about recording some audio using HTML5 and calculating the sha 512-bit digest. Then splitting this digest into two halfs and using them for AES 256-bit encryption (256-bit IV and 256-bit key) of a photo taken also with HTML5.

Is it safe to use this encrypted image as a replacement of /dev/(u)random? Which mode should I use for AES encryption?

share|improve this question
"Which mode should I use for AES encryption?" - None of them. Encryption is the wrong primitive here. You want to use a cryptographic PRNG (which may involve hashing low-entropy data, so it might use a hash function); but you really don't want to build one of those yourself, you're better off using a carefully-vetted scheme and implementation built by someone who knows this stuff cold. – D.W. May 14 '13 at 4:52
up vote 0 down vote accepted

Gathering binary data from a webcam/microphone can be a good (albeit unusual) source of entropy, yes. It's already been discussed here - see the second answer for some useful discussion. You mention 'encrypted image' but you probably mean 'hashed' - they're quite different things.

In terms of the mode of operation, GCM is a popular choice as it's an authenticated mode which provides data integrity as well as confidentiality. Of course, GCM isn't always available, in which case CTR and CBC are both fine, provided you MAC the ciphertext (and IV) to ensure integrity. Each mode has its own nuances (iv/nonce requirements, etc) so be sure read up on whichever mode you choose.

In case you haven't already, you should read up on some of the inherent weaknesses of javascript cryptography here. I'd be cautious about using any sort of automated tool to port a crypto library from one language to another... there's a lot that can go wrong.

Also, It's probably worth pointing out that as AES specifies a block size of 128 bits (regardless of whether the key is 128, 192, or 256 bits), the IV should also be 128 bits.

share|improve this answer
"Gathering binary data from a webcam/microphone" - This is not a good solution for a web application (written in Javascript, and running in the browser). First, only modern browsers support access to the webcam/microphone from Javascript (without using Flash), but if the user has a modern browser, it'll probably support window.crypto.getRandomValues() too, and in that case you're better off using the latter. Second, even if the browser allows access to webcam/microphone, it'll prompt the user to grant access. Users may be reluctant to grant your website that access; then whatcha gonna do? – D.W. May 14 '13 at 4:51
hunter: Thanks for the link to I'll read that. – user6929 May 14 '13 at 9:21
D.W.: 1) not all browsers that support webcam recording also support window.crypto.getRandomValues(). 2) I don't know, maybe then the JS app should not work at all ;) – user6929 May 14 '13 at 9:22

window.crypto.getRandomValues() is the best you can do. Unfortunately, at the time of writing, too many browsers don't support window.crypto.getRandomValues(): see Compatibility of window.crypto.getRandomValues().

The alternative is to use fallback methods. However, those fallback methods are kind've hacky, of dubious security, slow, and have other limitations. For more on the available fallback methods, see Generate cryptographically strong pseudorandom numbers in Javascript?.

Therefore, life kinda sucks. Basically, the best you can do is test for the existence of window.crypto.getRandomValues() using feature testing. If it exists, great! use it. If it doesn't exist, fall back to one of the fallback methods -- in that case, life is unhappy, but what can you do, there's no better option.

share|improve this answer
Speaking of hacky - it's possible to leverage flash APIs via javascript: . It's more likely that flash will be available on a user's system (excluding iOS, which is a big exclusion) as opposed to window.crypto.getRandomValues(), but if that's the case, then using a webcam might be redundant anyway as flash offers (as of v11) CS random numbers which give direct access to '/dev/random' ... more info here. – hunter May 14 '13 at 12:34

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.