Pourquoi écrire dans / dev / random ne rend pas la lecture parallèle depuis / dev / random plus rapide?

22

En général, la lecture de /dev/randomproduit de 100 à 500 octets et blocs, en attendant qu'une entropie soit collectée.

Pourquoi l'écriture d'informations /dev/randompar d'autres processus n'accélère-t-elle pas la lecture? Ne devrait-il pas fournir l'entropie requise?

Il peut être utile pour débloquer gpgun logiciel similaire sans le redémarrer et tout ressaisir, pour générer des clés non super-top secrètes, etc.

Vi.
la source
3
Il suffit de lire à la /dev/urandomplace. /dev/urandomest aussi sécurisé que /dev/randompour une utilisation cryptographique , le comportement de /dev/randomest une mauvaise conception.
Gilles 'SO- arrête d'être méchant'
1
Comment passer gpg --gen-keyde /dev/randomà /dev/urandomsans redémarrer?
Vi.
L'IIRC gpga /dev/randomcodé en dur. Vous pouvez changer votre configuration udev pour faire /dev/randomle même appareil que /dev/urandom, entre autres possibilités.
Gilles 'SO- arrête d'être méchant'
@Gilles, il nécessite toujours un redémarrage gpg --gen-key, donc ressaisir les données qu'il demande de manière interactive (ou en utilisant des méthodes plus intelligentes comme spécifier plus de paramètres de ligne de commande). Aussi le temps CPU générant le premier devrait être perdu (le gpg peut fonctionner une minute, imprimer quelques +es et demander des données aléatoires supplémentaires). Et ça donne le sentiment "revenons en arrière et allons sur une autre route" au lieu de "prenons un marteau et forçons-le vers l'avant" ...
Vi.

Réponses:

19

Vous pouvez écrire dans, /dev/randomcar cela fait partie de la manière de fournir des octets aléatoires supplémentaires à /dev/random, mais ce n'est pas suffisant, vous devez également informer le système qu'il existe une entropie supplémentaire via un ioctl()appel.

J'avais besoin des mêmes fonctionnalités pour tester mon programme de configuration de carte à puce , car je ne voulais pas attendre que ma souris / clavier génère suffisamment pour les plusieurs appels gpgqui ont été effectués pour chaque test. Ce que j'ai fait, c'est d'exécuter le programme Python, qui suit, en parallèle de mes tests. Bien sûr, il ne doit pas être utilisé du tout pour la gpggénération de clés réelles , car la chaîne aléatoire n'est pas du tout aléatoire (les informations aléatoires générées par le système seront toujours entrelacées). Si vous avez une source externe pour laquelle définir la chaîne random, vous devriez pouvoir avoir une entropie élevée. Vous pouvez vérifier l'entropie avec:

cat /proc/sys/kernel/random/entropy_avail

Le programme:

#!/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'oubliez pas de tuer le programme une fois que vous avez terminé.)

Anthon
la source
1
Une solution beaucoup plus simple serait d'utiliser rngd. Il est disponible sous forme de package dans la plupart (toutes?) Des distributions.
Patrick
4
random = "3420348024823049823-984230942049832423l4j2l42j"voir xkcd.com/221
user253751
@Patrick J'ai essayé au moins 3 solutions potentielles pour ajouter de l'aléatoire, le rngd de l'IIRC en faisait partie. Mais ils ne fonctionneraient pas tout de suite (cela pourrait être la configuration d'Ubuntu 12.04 à l'époque), et pour moi cette solution, avec 10 lignes de code, était plus simple.
Anthon
@Anthon: en tant que sidenote, je n'ai pas l'air xs4all.nl depuis que mitnik l'a utilisé pour stocker certaines choses, il y a des décennies ... :)
woliveirajr
@woliveirajr, mon compte hacktic.nl y a été transféré quelque part en 1992, j'y suis depuis un certain temps même si je ne vis pas aux Pays-Bas depuis plus de 20 ans maintenant.
Anthon
14

En règle générale, il est conçu par les développeurs du noyau et documenté dans 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
la source
1

Anthony a déjà expliqué que l'écriture sur /dev/randomn'augmente pas le nombre d'entropie et a montré comment l'ioctl RNDADDENTROPY (voir random (4) ) peut être utilisé pour créditer l'entropie. Ce n'est évidemment pas vraiment sécurisé, alors voici une alternative quand un générateur matériel de nombres aléatoires est disponible.

Les implémentations suivantes prennent 512 octets (4096 bits) de caractère aléatoire /dev/hwrnget le transmettent au pool d'entropie (créditant 4 bits d'entropie par octet, c'est un choix arbitraire de ma part). Après cela, il invoquera l' appel système select (2) pour bloquer lorsque le pool d'entropie est plein (documenté dans la page de manuel random (4) ).

Une version 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], [])

Étant donné que l'ISO Arch Linux n'avait pas Python installé, voici également une version 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
}

C'est probablement ce que fait le programme rngd (qui fait partie de rng-tools ) (non vérifié), sauf qu'il utilise des outils (Python ou Perl) qui sont déjà couramment disponibles.

Lekensteyn
la source
Si vous n'avez pas de générateur de nombres aléatoires matériel, vous pouvez utiliser /dev/urandomau lieu de /dev/hwrngsi vous ne vous souciez absolument pas des valeurs aléatoires non sécurisées .
Lekensteyn
Hmm, j'ai découvert que les périphériques hwrng génèrent automatiquement l'entropie en cas de besoin, aucun rngd ou script supplémentaire n'est nécessaire. Il existe cependant un bogue lorsque le getrandom()syscall est utilisé avec hwrng sur les noyaux antérieurs à 4.8-rc1 qui entraîne un comportement de blocage. Une solution de contournement est à read()deux fois /dev/random, voir github.com/Lekensteyn/archdir/commit/…
Lekensteyn