/ dev / random에 쓰는 것이 왜 / dev / random에서 병렬로 읽는 것이 더 빠르지 않습니까?


22

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

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

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


3
/dev/urandom대신 읽어보십시오 . 암호화 사용 /dev/urandom만큼 안전/dev/random 합니다. 동작 /dev/random은 잘못된 디자인입니다.
Gilles 'SO- 악한 중지'

1
어떻게 전환 gpg --gen-key에서 /dev/random/dev/urandom다시 시작하지 않고?
Vi.

IIRC gpg/dev/random하드 코딩되었습니다. udev 구성을 변경하여 다른 가능성 /dev/random과 동일한 장치 를 만들 /dev/urandom수 있습니다.
Gilles 'SO- 악마 그만해'

@Gilles는 다시 시작해야 gpg --gen-key하므로 대화식으로 요청하는 데이터를 다시 렌더링해야합니다 (또는 더 많은 명령 줄 매개 변수 지정과 같은 더 영리한 방법 사용). 또한 프라임 whould를 생성하는 CPU 시간이 손실됩니다 (gpg는 1 분 동안 작동하고 일부 +es를 인쇄 한 다음 추가 임의 데이터를 요청할 수 있음). 그리고 그것은 "망치로 가져 가서 앞으로 나아가 자"대신에 "돌아가서 다른 길로 가자"라는 느낌을줍니다
.

답변:


19

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

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


1
훨씬 간단한 해결책을 사용하는 것 rngd입니다. 대부분의 (모든?) 배포판에서 패키지로 제공됩니다.
Patrick

4
random = "3420348024823049823-984230942049832423l4j2l42j"xkcd.com/221
user253751

@ 패트릭 나는 무작위성을 추가하기 위해 적어도 3 가지 잠재적 솔루션을 시도했지만 IIRC rngd는 그중 하나였습니다. 그러나 그들은 즉시 작동하지 않을 것입니다 (당시 Ubuntu 12.04 설정 일 수 있음).이 솔루션은 10 줄의 코드로 더 간단했습니다.
Anthon

@Anthon : 참고로, mitnik이 수십 년 전에 물건을 저장하는 데 사용한 이후 xs4all.nl처럼 보이지 않았습니다 ... :)
woliveirajr

@ woliveirajr, 1992 년 어딘가에 hacktic.nl에서 내 계정을 이전했지만 20 년 이상 네덜란드에 살지 않았지만 얼마 동안 머물 렀습니다.
Anthon

14

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

1

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의 일부 )이 수행 한 것입니다.


하드웨어 난수 생성기가없는 경우 안전하지 않은 난수를 신경 쓰지 /dev/urandom않고 대신 사용할 수 있습니다 . /dev/hwrng
Lekensteyn

흠, hwrng 장치가 필요할 때 자동으로 엔트로피를 생성하며 추가 rngd 또는 스크립트가 필요하지 않음을 발견했습니다. getrandom()4.8-rc1 이전의 커널 에서 syscall을 hwrng와 함께 사용하면 블로킹 동작 이 발생하는 버그 가 있습니다. 해결 방법은에서 read()두 번입니다 ( github.com/Lekensteyn/archdir/commit/…/dev/random 참조)
Lekensteyn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.