3

I'd like to generate some random passwords using Emacs, and thus need a secure random number generator. I don't like that 'random might be seeded from system time

I'd feel most comfortable just reading from /dev/urandom:

(insert-file-contents-literally "/dev/urandom" nil 0 32)

Unfortunately Emacs complains with insert-file-contents-literally: not a regular file: /dev/urandom

Is there another way of reading from urandom or generating secure numbers?

EDIT: Looking at the source of 'random, I see that it's using libc rand(), which is another notch against using 'random for passwords (see this question)

Felipe
  • 329
  • 1
  • 8
  • I don't believe this is possible, but you could call `cat` on this file for example. – wvxvw Sep 19 '17 at 14:28
  • 1
    Not what you ask, but looking at source code of `random` in `fns.c` points to function `init_random()` defined in `sysdep.c` which happens to read `/dev/urandom`. – JeanPierre Sep 19 '17 at 14:29
  • Are you going to have your users type these passwords back into emacs to access something? Or will they use the password on some other system? If back into emacs, consider that emacs is the very definition of a system on which an attacker can execute arbitrary code. Before worrying too much about how good your seed is, I would consider what the entire attack surface looks like. If you're confident that no attacker can access emacs, either during the process of making or using a password, then worry about your seed. – Rodney Price Sep 20 '17 at 04:51
  • I just want to have an emacs-based replacement for https://randomkeygen.com – Felipe Sep 20 '17 at 06:11
  • @JeanPierre It looks like it at first glance but fns.c is calling `get_random()` instead of `getrandom()`. `get_random()` defined in `sysdep.c`, which in turn is calling `random()`, which is not securely random as described in https://stackoverflow.com/questions/14678957/libc-random-number-generator-flawed. So while `init_random()`, also defined in `sysdep.c` sets the seed with entropy from `/dev/urandom` it doesn't really help, because `random()` is flawed. – fap May 12 '23 at 19:57

1 Answers1

2

You could use the approach described in this article, which uses a call to head to get the first bits/8 bytes from /dev/urandom using the following snippet:

(with-temp-buffer (set-buffer-multibyte nil) 
  (call-process "head" "/dev/urandom" t nil "-c" (format "%d" (/ bits 8))) 
  (let ((f (apply-partially #'format "%02x"))) 
    (concat "16#" (mapconcat f (buffer-string) ""))))
Arnot
  • 671
  • 1
  • 5
  • 15