ProgramingTip

C에서 / dev / random 또는 urandom을 사용하는 방법은 무엇입니까?

bestdevel 2020. 10. 26. 08:26
반응형

C에서 / dev / random 또는 urandom을 사용하는 방법은 무엇입니까?


/dev/random또는 /dev/urandomC에서 사용하고 싶습니다 . 어떻게 할 수 있습니까? C로 어떻게 처리 할 수 ​​있는지 모르겠습니다. 누군가 알고있는 방법을 알려주세요. 감사합니다.


일반적으로 절차에 실패한 지점이 얼마나 많기 때문에 임의의 데이터를 위해 파일을 열지 않는 것이 좋습니다.

의 리눅스 배포판 최근에서 시스템 콜은 암호화 보안이 난수를 가져올 수 있습니다, 실패 할 수 그것은없는 경우 입니다 하지 플래그로 지정하고 읽기 금액은 대부분 256 바이트이다.getrandom GRND_RANDOM

2017 년 10 월 현재 OpenBSD, Darwin 및 Linux (와 함께 -lbsd)는 모두 암호화 보안이 구현 되어서 실패 할 수 없습니다. 이는 매우 매력적인 옵션이됩니다.arc4random

char myRandomData[50];
arc4random_buf(myRandomData, sizeof myRandomData); // done!

확장 된 임의의 장치를 파일 인 것처럼 사용할 수 있습니다. 당신은 그들로부터로부터 독립된 데이터를 얻습니다. 나는 open/ read여기를 사용하고 fopen/ fread잘 작동합니다.

int randomData = open("/dev/urandom", O_RDONLY);
if (randomData < 0)
{
    // something went wrong
}
else
{
    char myRandomData[50];
    ssize_t result = read(randomData, myRandomData, sizeof myRandomData);
    if (result < 0)
    {
        // something went wrong
    }
}

파일 설명을 전에 더 많은 임의의 바이트를 읽을 수 있습니다. / dev / urandom은 시스템 호출이 신호에 의해 중단되지 않고 한 차단하지 않고 요청한만큼의 바이트를 항상 채. 암호화 된 보안으로 강화되고 이동하는 임의의 장치가 있습니다.

/ dev / random은 더 까다 롭습니다. 대부분의 플랫폼에서 요청한 것보다 약간의 바이트를 반환 할 수 있고 사용 가능한 바이트가 충분하지 않을 수 있습니다. 이 오류 처리 이야기를 더 복잡하게 만듭니다.

int randomData = open("/dev/random", O_RDONLY);
if (randomData < 0)
{
    // something went wrong
}
else
{
    char myRandomData[50];
    size_t randomDataLen = 0;
    while (randomDataLen < sizeof myRandomData)
    {
        ssize_t result = read(randomData, myRandomData + randomDataLen, (sizeof myRandomData) - randomDataLen);
        if (result < 0)
        {
            // something went wrong
        }
        randomDataLen += result;
    }
    close(randomData);
}

위에 다른 답변이 있습니다. FILE*그래도 스트림 찾았습니다 . 내가 한 일은 ...

int byte_count = 64;
char data[64];
FILE *fp;
fp = fopen("/dev/urandom", "r");
fread(&data, 1, byte_count, fp);
fclose(fp);


읽기 위해 파일을 연 다음 데이터를 보유하고 있습니다. C ++ 11에서는 std::random_device현재 장치에 대한 교차 플랫폼 액세스를 제공 하는 것을 사용할 수 있습니다.


Zneak 은 100 %입니다. 또한 시작시 필요한 것보다 약간 큰 난수 버퍼를 읽는 것도 매우 일반적입니다. 그런 다음 메모리에 배열을 채우거나 나중에 쓸 수 있습니다.

위의 일반적인 구현 :

typedef struct prandom {
     struct prandom *prev;
     int64_t number;
     struct prandom *next;
} prandom_t;

이것은 필요에 따라 다른 많은 것에 의해 마술처럼 보충 될 수있는 단지 전진하는 테이프와 유사 해입니다. 있습니다 많은서비스 등 더욱 강력한 발전기로 생성되는 것도 있지만, 임의의 숫자의 큰 파일 덤프를 제공합니다 :

  • 방사성 붕괴
  • 광학적 동작 (반투명 거울에 부딪 치는 광자)
  • 대기 소음 (위만큼 강하지 않음)
  • 술에 취한 원숭이가 키보드로 입력하고 마우스를 움직이는 농장 (농담)

말할 것도없이 진행되지 않는 경우를 대비 하여 암호화 시드에 '사전 패키지 된'엔트로피를 사용하지 마십시오 . 이러한 세트는 시뮬레이션에 적합하며 키 생성 에는 전혀 적합 하지 않습니다 .

품질에 신경 쓰지 않고 몬테카를로 시뮬레이션과 같이 많은 숫자가 필요한 경우 read ()가 차단되지 않도록하는 방식으로 숫자를 사용하는 것이 훨씬 좋습니다.

그러나 숫자의 임의성은 생성과 관련된 복잡성만큼 결정적이라는 것을 기억하십시오. /dev/random하고 /dev/urandom편리하지만, HRNG를 사용하여 (또는 HRNG에서 큰 덤프 다운로드)만큼 강하지 않다. 또한 /dev/random 엔트로피를 통해 리필 되므로 상황에 따라 꽤 오랫동안 차단 될 수 있습니다.


zneak의 답변은 간단하게 다루지 만 현실은 그보다 더 복잡합니다. 예를 들어, 처음부터 / dev / {u} random이 실제로 난수 장치인지 여부를 고려해야합니다. 이러한 시나리오는 시스템이 손상되고 장치가 / dev / zero 또는 스파 스 파일에 대한 심볼릭 링크로 교체 된 경우 발생할 수 있습니다. 이런 일이 발생하면 이제 랜덤 스트림을 완전히 예측할 수 있습니다.

가장 간단한 방법 (적어도 Linux 및 FreeBSD에서는)은 장치가 임의 생성기 인 경우에만 성공할 장치에서 ioctl 호출을 수행하는 것입니다.

int data;
int result = ioctl(fd, RNDGETENTCNT, &data); 
// Upon success data now contains amount of entropy available in bits

이 작업이 임의의 장치를 처음 읽기 전에 수행되면 임의의 장치를 가지고 있다는 공정한 내기가 있습니다. 따라서 @zneak의 답변은 다음과 같이 확장 할 수 있습니다.

int randomData = open("/dev/random", O_RDONLY);
int entropy;
int result = ioctl(randomData, RNDGETENTCNT, &entropy);

if (!result) {
   // Error - /dev/random isn't actually a random device
   return;
}

if (entropy < sizeof(int) * 8) {
    // Error - there's not enough bits of entropy in the random device to fill the buffer
    return;
}

int myRandomInteger;
size_t randomDataLen = 0;
while (randomDataLen < sizeof myRandomInteger)
{
    ssize_t result = read(randomData, ((char*)&myRandomInteger) + randomDataLen, (sizeof myRandomInteger) - randomDataLen);
    if (result < 0)
    {
        // error, unable to read /dev/random 
    }
    randomDataLen += result;
}
close(randomData);

Insane Coding 블로그 는 이것과 얼마 전까지 만해도 다른 함정을 다루었습니다 . 전체 기사를 읽는 것이 좋습니다. 나는이 솔루션이 어디에서 나온 것인지 그들의 공로를 인정해야합니다.

추가 편집 (2014-07-25) ...
공동 우연히 어젯밤에 LibReSSL 노력의 일환 으로 Linux가 GetRandom () syscall을 받는 것으로 보입니다 . 글을 쓰는 시점에서 커널 일반 릴리스에서 언제 사용할 수 있을지에 대한 단어가 없습니다. 그러나 이것은 파일을 통한 액세스가 제공하는 모든 함정을 제거하므로 암호화로 안전한 임의 데이터를 얻는 데 선호되는 인터페이스입니다. LibReSSL 가능한 구현 도 참조하십시오 .

참고 URL : https://stackoverflow.com/questions/2572366/how-to-use-dev-random-or-urandom-in-c

반응형