C에서 /dev/random 또는 urandom을 사용하는 방법
사용하고 싶다/dev/random
또는/dev/urandom
어떻게 하면 좋을까요?C에서 어떻게 대처해야 할지 모르겠으니, 아는 사람이 있으면 가르쳐 주세요.감사합니다.
일반적으로 랜덤 데이터를 얻기 위해 파일을 열지 않는 것이 좋습니다. 절차에는 장애 지점이 많기 때문입니다.
최근의 Linux 디스트리뷰션에서는 시스템콜을 사용하여 암호 시큐어 랜덤 번호를 취득할 수 있습니다.또, 다음과 같은 경우는 실패하지 않습니다. GRND_RANDOM
는 플래그로 지정되지 않았으며 판독량은 최대 256바이트입니다.
2017년 10월 현재 OpenBSD, Darwin 및 Linux (와-lbsd
)는, 모두 암호화 시큐어이며, 장해가 발생하지 않는 실장이 되어 있습니다.그 때문에, 매우 매력적인 옵션이 됩니다.
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/module은 더 까다롭습니다.대부분의 플랫폼에서는 요청된 것보다 적은 바이트를 반환할 수 있으며 사용 가능한 바이트가 부족할 경우 차단할 수 있습니다.이로 인해 오류 처리 과정이 더욱 복잡해집니다.
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);
}
zneak의 대답은 단순하지만 현실은 그보다 더 복잡하다.예를 들어, 애초에 /dev/{u}random이 정말로 난수 디바이스인지 여부를 고려해야 합니다.이러한 시나리오는 시스템이 손상되어 디바이스가 /dev/zero에 대한 심볼링크 또는 스파스 파일로 대체된 경우에 발생할 수 있습니다.이 경우 랜덤스트림은 완전히 예측 가능합니다.
가장 심플한 방법(최소한 Linux 및 FreeB의 경우)SD)는 디바이스에 대해 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);
얼마 전 '미치광이 코딩' 블로그에서 이 문제와 다른 함정들을 다뤘습니다. 기사 전체를 읽을 것을 강력히 추천합니다.이 솔루션이 어디서 나왔는지 그들의 공로를 인정해야 합니다.
★★★★★★★★(2014-07-25)...
공교롭게도, 어젯밤에 리브리의 일부로서SSL 작업. Linux가 GetRandom() syscall을 취득하고 있는 것 같습니다.기입 시점에서는, 커널의 일반 릴리스에서는 언제 이용할 수 있을지에 대해서는 아무것도 알 수 없습니다.그러나 파일을 통한 액세스가 제공하는 모든 함정을 제거하므로 암호화 방식으로 안전한 랜덤 데이터를 얻으려면 이 인터페이스가 선호됩니다.'LibRe'도 참조해 주세요.SSL 실장 가능.
위의 다른 정확한 답변이 있습니다.는 '아까부터'를 요.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
엔트로피를 통해 보충하기 때문에 상황에 따라서는 한동안 차단될 수 있습니다.
언급URL : https://stackoverflow.com/questions/2572366/how-to-use-dev-random-or-urandom-in-c
'programing' 카테고리의 다른 글
Vue 클래스 구성 요소에서 필터를 정의하려면 어떻게 해야 합니까? (0) | 2022.07.08 |
---|---|
정적 라이브러리와 공유 라이브러리의 차이점 (0) | 2022.07.08 |
vue.js에서 스타일을 계산하거나 사용하는 방법 (0) | 2022.07.08 |
파이 차트가 완전히 렌더링되지 않음 (0) | 2022.07.08 |
POSIX 스레드 및 신호 (0) | 2022.07.08 |