Mengapa menulis ke / dev / random tidak membuat pembacaan paralel dari / dev / random lebih cepat?

22

Biasanya membaca dari /dev/randommenghasilkan 100-500 byte dan blok, menunggu entropi dikumpulkan.

Mengapa tidak menulis informasi /dev/randommelalui proses lain mempercepat membaca? Bukankah seharusnya memberikan entropi yang diperlukan?

Ini dapat berguna untuk membuka blokir gpgatau perangkat lunak serupa tanpa memulai ulang dan memasukkan kembali semuanya, untuk menghasilkan kunci non-super-rahasia, dll.

Vi.
sumber
3
Baca saja dari /dev/urandom. /dev/urandomadalah sebagai aman sebagai /dev/randomuntuk digunakan kriptografi , perilaku /dev/randomadalah desain yang buruk.
Gilles 'SO- berhenti bersikap jahat'
1
Cara beralih gpg --gen-keydari /dev/randomke /dev/urandomtanpa restart?
Vi.
IIRC gpgmemiliki /dev/randomhard-coded. Anda dapat mengubah konfigurasi udev Anda untuk membuat /dev/randomperangkat yang sama dengan /dev/urandom, di antara kemungkinan lainnya.
Gilles 'SO- berhenti bersikap jahat'
@Gilles, masih membutuhkan pengaktifan ulang gpg --gen-key, oleh karena itu menyokong kembali data yang diminta secara interaktif (atau menggunakan metode yang lebih pintar seperti menentukan lebih banyak parameter baris perintah). Juga waktu CPU yang menghasilkan prime akan hilang (gpg dapat bekerja sebentar, mencetak beberapa +es dan kemudian meminta data acak tambahan). Dan itu memberi perasaan "ayo kembali dan pergi ke rute lain" alih-alih "ayo palu dan paksakan maju" ...
Vi.

Jawaban:

19

Anda dapat menulis /dev/randomkarena itu adalah bagian dari cara untuk memberikan byte acak tambahan /dev/random, tetapi itu tidak cukup, Anda juga harus memberi tahu sistem bahwa ada entropi tambahan melalui ioctl()panggilan.

Saya membutuhkan fungsionalitas yang sama untuk menguji program pengaturan kartu pintar saya , karena saya tidak ingin menunggu mouse / keyboard saya menghasilkan cukup untuk beberapa panggilan gpgyang dibuat untuk setiap uji coba. Apa yang saya lakukan adalah menjalankan program Python, yang mengikuti, secara paralel dengan tes saya. Itu tentu saja tidak boleh digunakan sama sekali untuk gpgpembuatan kunci nyata , karena string acak tidak acak sama sekali (sistem yang dihasilkan info acak masih akan disisipkan). Jika Anda memiliki sumber eksternal untuk mengatur string random, maka Anda harus dapat memiliki entropi tinggi. Anda dapat memeriksa entropi dengan:

cat /proc/sys/kernel/random/entropy_avail

Program:

#!/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)

(Jangan lupa untuk mematikan program setelah Anda selesai.)

Anthon
sumber
1
Solusi yang jauh lebih sederhana adalah menggunakan rngd. Ini tersedia sebagai paket di sebagian besar (semua?) Distro.
Patrick
4
random = "3420348024823049823-984230942049832423l4j2l42j"lihat xkcd.com/221
user253751
@ Patrick Saya mencoba setidaknya 3 solusi potensial untuk menambah keacakan, IIRC rngd adalah salah satunya. Tetapi mereka tidak akan bekerja di luar kotak (bisa jadi setup Ubuntu 12.04 pada saat itu), dan bagi saya solusi ini, dengan 10 baris kode, lebih sederhana.
Anthon
@Anthon: sebagai sidenote, saya belum tampak xs4all.nl sejak mitnik menggunakannya untuk menyimpan beberapa hal, beberapa dekade yang lalu ... :)
woliveirajr
@woliveirajr, saya punya akun dari hacktic.nl ditransfer ke suatu tempat pada tahun 1992, saya telah berada di sana sementara waktu meskipun saya belum tinggal di Belanda selama lebih dari 20 tahun sekarang.
Anthon
14

Biasanya, ini dirancang oleh pengembang kernel dan didokumentasikan dalam 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
sumber
1

Anthony sudah menjelaskan bahwa menulis untuk /dev/randomtidak meningkatkan jumlah entropi dan menunjukkan bagaimana RNDADDENTROPY ioctl (lihat acak (4) ) dapat digunakan untuk kredit untuk entropi. Ini jelas tidak benar-benar aman, jadi di sini ada alternatif ketika generator nomor acak perangkat keras tersedia.

Implementasi berikut mengambil 512 byte (4096 bit) dari keacakan /dev/hwrngdan meneruskannya ke kumpulan entropi (mengkredit 4 bit entropi per byte, ini adalah pilihan sewenang-wenang dari saya). Setelah itu akan memanggil syscall pilih (2) untuk memblokir ketika kumpulan entropi penuh (didokumentasikan dalam manual acak (4) ).

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

Karena iso Arch Linux tidak memiliki Python diinstal, berikut adalah versi Perl juga:

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
}

Ini mungkin apa yang dilakukan oleh program rngd (bagian dari rng-tools ) (tidak terverifikasi), kecuali bahwa ia menggunakan alat (Python atau Perl) yang sudah umum tersedia.

Lekensteyn
sumber
Jika Anda tidak memiliki generator nomor acak perangkat keras, Anda bisa menggunakan /dev/urandomalih-alih /dev/hwrngjika Anda sama sekali tidak peduli dengan nilai acak tidak aman .
Lekensteyn
Hmm, saya menemukan bahwa perangkat hwrng secara otomatis menghasilkan entropi saat dibutuhkan, tidak ada rngd atau skrip tambahan yang diperlukan. Ada bug meskipun ketika getrandom()syscall digunakan dengan hwrng pada kernel yang lebih tua dari 4,8-rc1 yang menghasilkan perilaku memblokir. Solusinya adalah read()dua kali dari /dev/random, lihat github.com/Lekensteyn/archdir/commit/…
Lekensteyn