/ dev / random에 쓰는 것이 왜 / dev / random에서 병렬로 읽는 것이 더 빠르지 않습니까? 필요한 엔트로피를 제공하지 않아야합니까? gpg슈퍼 비밀 키가

일반적으로 읽은 값 /dev/random은 100-500 바이트 및 블록 을 생성하여 엔트로피가 수집 될 때까지 기다립니다.

/dev/random다른 프로세스에서 정보를 쓰는 것이 읽기 속도를 높이 지 않는 이유는 무엇 입니까? 필요한 엔트로피를 제공하지 않아야합니까?

gpg슈퍼 비밀 키가 아닌 키 생성 등을 다시 시작하지 않고 모든 것을 다시 입력하지 않고도 차단 해제 또는 유사한 소프트웨어에 유용 할 수 있습니다 .



답변

/dev/random추가 임의 바이트를 제공하는 방법의 일부이기 때문에 쓸 수 /dev/random있지만 충분하지 않으며 ioctl()호출을 통해 추가 엔트로피가 있음을 시스템에 알려야합니다 .

마우스 / 키보드가 각 테스트 실행에 대해 여러 번 호출 될 때까지 마우스 / 키보드가 생성 될 때까지 기다리지 않기 때문에 스마트 카드 설정 프로그램 을 테스트하는 데 동일한 기능이 필요했습니다 gpg. 내가 한 일은 내 테스트와 동시에 Python 프로그램을 실행하는 것입니다. 무작위 문자열이 전혀 무작위가 아니기 때문에 실제 키 생성 에 전혀 사용 해서는 안됩니다gpg (시스템 생성 무작위 정보는 여전히 인터리브됩니다). 에 대한 문자열을 설정할 외부 소스가 있으면 random엔트로피가 높아야합니다. 다음을 통해 엔트로피를 확인할 수 있습니다.

cat /proc/sys/kernel/random/entropy_avail

프로그램:

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

(완료 후 프로그램을 종료하는 것을 잊지 마십시오.)


답변

일반적으로 커널 개발자가 설계했으며 다음과 같이 문서화되어 있습니다 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.

답변

Anthony는 이미 /dev/random엔트로피 수를 늘리지 않고 RNDADDENTROPY ioctl ( random (4) 참조 )을 사용 하여 엔트로피를 계산하는 방법을 보여주었습니다 . 확실히 안전하지는 않으므로 하드웨어 난수 생성기를 사용할 수있는 경우 대안이 있습니다.

다음 구현은 512 바이트 (4096 비트)의 임의성을 가져 /dev/hwrng와서 엔트로피 풀로 전달합니다 (바이트 당 4 비트의 엔트로피를 신용하는 것은 나에게 임의의 선택입니다). 그런 다음 select (2) syscall을 호출하여 엔트로피 풀이 가득 찼을 때 차단합니다 ( random (4) 맨 페이지에 설명되어 있음).

파이썬 버전 :

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

Arch Linux iso에는 Python이 설치되어 있지 않으므로 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
}

rngd 프로그램 ( rng-tools의 일부 )은 이미 일반적으로 사용 가능한 도구 (Python 또는 Perl)를 사용한다는 점을 제외하고 는 rngd 프로그램 ( rng-tools의 일부 )이 수행 한 것입니다.