Por que escrever em / dev / random não torna a leitura paralela de / dev / random mais rápida?

22

Normalmente, a leitura de /dev/randomproduz 100-500 bytes e blocos, aguardando a coleta de uma entropia.

Por que gravar informações em /dev/randomoutros processos não acelera a leitura? Não deveria fornecer a entropia necessária?

Pode ser útil para desbloquear gpgsoftware semelhante ou sem precisar reiniciá-lo e reinserir tudo, para gerar chaves não super secretas, etc.

Vi.
fonte
3
Basta ler em /dev/urandomvez disso. /dev/urandomé tão seguro quanto /dev/randompara uso criptográfico , o comportamento de /dev/randomum design ruim.
Gilles 'SO- stop be evil'
1
Como mudar gpg --gen-keyde /dev/randompara /dev/urandomsem reiniciar?
Vi.
O IIRC gpgfoi /dev/randomcodificado. Você pode alterar sua configuração do udev para criar /dev/randomo mesmo dispositivo /dev/urandom, entre outras possibilidades.
Gilles 'SO- stop be evil'
@Gilles, ainda é necessário reiniciar gpg --gen-key, portanto, reenviar os dados solicitados interativamente (ou usar métodos mais inteligentes, como especificar mais parâmetros de linha de comando). Além disso, o tempo de CPU que gera o prime deve ser perdido (o gpg pode funcionar por um minuto, imprimir alguns +es e solicitar dados aleatórios adicionais). E dá a sensação de "vamos voltar e seguir outra rota" em vez de "vamos pegar um martelo e forçá-lo adiante" ...
Vi.

Respostas:

19

Você pode escrever /dev/randomporque é parte do caminho fornecer bytes aleatórios extras para /dev/random, mas não é suficiente, também é necessário notificar o sistema de que há entropia adicional por meio de uma ioctl()chamada.

Eu precisava da mesma funcionalidade para testar meu programa de configuração de cartão inteligente , pois não queria esperar que o mouse / teclado gerasse o suficiente para as várias chamadas gpgfeitas para cada execução de teste. O que fiz foi executar o programa Python, a seguir, paralelamente aos meus testes. É claro que não deve ser usado para a gpggeração real de chaves, pois a sequência aleatória não é aleatória (as informações aleatórias geradas pelo sistema ainda serão intercaladas). Se você tiver uma fonte externa para a qual definir a sequência random, poderá conseguir alta entropia. Você pode verificar a entropia com:

cat /proc/sys/kernel/random/entropy_avail

O programa:

#!/usr/bin/env python
# For testing purposes only 
# DO NOT USE THIS, THIS DOES NOT PROVIDE ENTROPY TO /dev/random, JUST BYTES

import fcntl
import time
import struct

RNDADDENTROPY=0x40085203

while True:
    random = "3420348024823049823-984230942049832423l4j2l42j"
    t = struct.pack("ii32s", 8, 32, random)
    with open("/dev/random", mode='wb') as fp:
        # as fp has a method fileno(), you can pass it to ioctl
        res = fcntl.ioctl(fp, RNDADDENTROPY, t)
    time.sleep(0.001)

(Não esqueça de interromper o programa depois que terminar.)

Anthon
fonte
1
Solução muito mais simples seria usar rngd. Está disponível como um pacote na maioria das distribuições (todas?).
217 Patrick Patrick
4
random = "3420348024823049823-984230942049832423l4j2l42j"consulte xkcd.com/221
user253751
@ Patrick Tentei pelo menos três soluções em potencial para adicionar aleatoriedade, o IIRC rngd foi uma delas. Mas eles não funcionariam imediatamente (poderia ser a instalação do Ubuntu 12.04 na época), e para mim essa solução, com 10 linhas de código, era mais simples.
Anthon
@Anthon: Como nota, eu não parecem xs4all.nl desde Mitnik usado para armazenar algumas coisas, décadas atrás ... :)
woliveirajr
@woliveirajr, eu tive minha conta do hacktic.nl transferida para algum lugar em 1992, estou lá há algum tempo, embora não moro na Holanda há mais de 20 anos.
Anthon
14

Normalmente, ele é projetado por desenvolvedores de kernel e documentado em man 4 random:

Writing to /dev/random or /dev/urandom will update the entropy pool
with the data written, but this will not result in a higher entropy
count.  This means that it will impact the contents read from both
files, but it will not make reads from /dev/random faster.
cuonglm
fonte
1

Anthony já explicou que escrever para /dev/randomnão aumenta a contagem de entropia e mostrou como o RNDADDENTROPY ioctl (veja aleatório (4) ) pode ser usado para creditar pela entropia. Obviamente, não é realmente seguro, então aqui está uma alternativa quando um gerador de números aleatórios de hardware está disponível.

As implementações a seguir recebem 512 bytes (4096 bits) de aleatoriedade /dev/hwrnge a encaminham para o pool de entropia (creditando 4 bits de entropia por byte, essa é uma escolha arbitrária minha). Depois disso, ele chamará o syscall select (2) para bloquear quando o conjunto de entropia estiver cheio (documentado na página de manual aleatória (4) ).

Uma versão Python:

import fcntl, select, struct
with open('/dev/hwrng', 'rb') as hw, open('/dev/random') as rnd:
    while True:
        d = hw.read(512)
        fcntl.ioctl(rnd, 0x40085203, struct.pack('ii', 4 * len(d), len(d)) + d)
        select.select([], [rnd], [])

Como o iso do Arch Linux não possui o Python instalado, aqui também está uma versão do Perl:

open my $hw, "</dev/hwrng" and open my $rnd, "</dev/random" or die;
for (;;) {
    my $l = read $hw, my $d, 512;
    ioctl $rnd, 0x40085203, pack("ii", 4 * $l, $l) . $d or die;
    vec(my $w, fileno $rnd, 1) = 1;
    select undef, $w, undef, undef
}

Provavelmente é isso que o programa rngd (parte do rng-tools ) faz (não verificado), exceto pelo uso de ferramentas (Python ou Perl) que já estão disponíveis.

Lekensteyn
fonte
Se você não tiver um gerador de números aleatórios de hardware, poderá usar em /dev/urandomvez de /dev/hwrngabsolutamente não se importar com valores aleatórios inseguros .
Lekensteyn
Hmm, descobri que os dispositivos hwrng geram automaticamente entropia quando necessário, sem necessidade de rngd ou script adicional. No entanto, existe um erro quando o getrandom()syscall é usado com hwrng em kernels anteriores a 4.8-rc1 que resulta em comportamento de bloqueio. Uma solução alternativa é read()duas vezes /dev/random, consulte github.com/Lekensteyn/archdir/commit/…
Lekensteyn