[java] 느린 SecureRandom 생성기를 처리하는 방법?
Java에서 암호화 적으로 강력한 난수를 원하면을 사용하십시오 SecureRandom
. 불행히도 SecureRandom
매우 느릴 수 있습니다. /dev/random
Linux에서 사용 하는 경우 충분한 엔트로피가 빌드되기를 기다리는 것을 차단할 수 있습니다. 성능 저하를 어떻게 피합니까?
누구든지이 문제에 대한 해결책으로 흔하지 않은 수학 을 사용 했습니까?
JDK 6에서이 성능 문제가 해결되었음을 확인할 수 있습니까?
답변
진정한 무작위 데이터를 원한다면 불행히도 기다려야합니다. 여기에는 SecureRandom
PRNG 의 시드가 포함됩니다 . SecureRandom
인터넷에 연결하여 특정 웹 사이트에서 시드 데이터를 다운로드 할 수 있지만 드문 수학은보다 빠른 실제 임의 데이터를 수집 할 수 없습니다 . 내 생각에 이것은 /dev/random
가능한 곳 보다 빠를 것 같지 않습니다 .
PRNG를 원하면 다음과 같이하십시오.
SecureRandom.getInstance("SHA1PRNG");
지원되는 문자열은 SecureRandom
SPI 공급자 에 따라 다르지만 Security.getProviders()
and를 사용하여 열거 할 수 있습니다 Provider.getService()
.
Sun은 SHA1PRNG를 좋아하므로 광범위하게 사용할 수 있습니다. PRNG가 진행되는 속도는 특히 빠르지는 않지만 PRNG는 엔트로피의 물리적 측정을 차단하지 않고 크 런칭 수치입니다.
예외는 호출하지 않는 경우이다 setSeed()
데이터를 얻기 전에, 다음 PRNG 당신이 전화를 처음 한 번 자신을 배정한다 next()
나 nextBytes()
. 일반적으로 시스템에서 상당히 적은 양의 실제 임의 데이터를 사용하여이 작업을 수행합니다. 이 호출은 차단 될 수 있지만 “PID와 함께 현재 시간을 해시하고 27을 추가하며 최선을 다함”의 변형보다 임의의 수의 소스를 훨씬 더 안전하게 만듭니다. 그래도 게임에 임의의 숫자 만 필요하거나 테스트 목적으로 동일한 시드를 사용하여 나중에 스트림을 반복 할 수있게하려면 안전하지 않은 시드가 여전히 유용합니다.
답변
다음을 사용하여 Linux에서 가장 빠르지 만 약간 안전하지 않은 / dev / urandom을 선택할 수 있어야합니다.
-Djava.security.egd=file:/dev/urandom
그러나 이것은 Java 5 이상 ( Java Bug 6202721 ) 에서는 작동하지 않습니다 . 제안 된 해결 방법은 다음을 사용하는 것입니다.
-Djava.security.egd=file:/dev/./urandom
(추가 참고 /./
)
답변
Linux에서 기본 구현 SecureRandom
은 NativePRNG
(소스 코드 here )이며 속도가 매우 느립니다. Windows에서 기본값은이며 SHA1PRNG
, 다른 사람들이 지적했듯이 명시 적으로 지정하면 Linux에서도 사용할 수 있습니다.
NativePRNG
운영 체제에서 (로부터 읽음) 엔트로피를 지속적으로 수신한다는 점에서 SHA1PRNG
Maths의 AESCounterRNG 와 다릅니다 /dev/urandom
. 다른 PRNG는 시딩 후 추가 엔트로피를 얻지 못합니다.
AESCounterRNG는 약 10 배 빠르며 SHA1PRNG
, IIRC 자체는 2 배 또는 3 배 빠릅니다 NativePRNG
.
초기화 후 엔트로피를 획득하는 더 빠른 PRNG가 필요한 경우 Fortuna 의 Java 구현을 찾을 수 있는지 확인하십시오 . Fortuna 구현의 핵심 PRNG는 AESCounterRNG에서 사용하는 것과 동일하지만 엔트로피 풀링 및 자동 시드의 정교한 시스템도 있습니다.
답변
많은 Linux 배포판 (대부분 데비안 기반) /dev/random
은 엔트로피 에 사용하도록 OpenJDK를 구성합니다 .
/dev/random
정의상 느리고 차단할 수도 있습니다.
여기에서 차단을 해제하는 방법에 대한 두 가지 옵션이 있습니다.
- 엔트로피 개선 또는
- 임의성 요구 사항을 줄입니다.
옵션 1, 엔트로피 개선
에 대한 엔트로피를 더 얻으려면 haveged 데몬을 /dev/random
사용해보십시오 . HAVEGE 엔트로피를 지속적으로 수집하는 데몬이며 특별한 하드웨어가 필요하지 않고 CPU 자체와 시계 만 필요하므로 가상화 환경에서도 작동합니다.
우분투 / 데비안에서 :
apt-get install haveged
update-rc.d haveged defaults
service haveged start
RHEL / CentOS에서 :
yum install haveged
systemctl enable haveged
systemctl start haveged
옵션 2. 임의성 요구 사항 감소
어떤 이유로 든 위의 솔루션이 도움이되지 않거나 암호로 강력한 임의성을 신경 쓰지 않으면 /dev/urandom
대신 차단으로 전환 할 수 있습니다 .
전체적으로 수행하려면 jre/lib/security/java.security
기본 Java 설치에서 사용할 파일 을 편집하십시오 /dev/urandom
(다른 버그 로 인해 으로 지정되어야 함 /dev/./urandom
).
이처럼 :
#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom
그런 다음 명령 줄에서 지정할 필요가 없습니다.
참고 : 암호화를 수행하는 경우 엔트로피 가 양호 해야 합니다. 사례- 안드로이드 PRNG 문제 로 비트 코인 지갑의 보안이 저하되었습니다.
답변
SecureRandom
헤드리스 데비안 서버에서 한 번에 약 25 초 동안 전화 차단 과 비슷한 문제가있었습니다 . haveged
데몬을 설치하여 /dev/random
헤드리스 서버에 필요한 엔트로피를 생성하려면 이와 같은 것이 필요합니다. 전화를 걸려면 SecureRandom
아마도 밀리 초가 걸릴 것입니다.
답변
진정으로 “암호 적으로 강력한”임의성을 원한다면 강력한 엔트로피 소스가 필요합니다. /dev/random
시스템 이벤트가 엔트로피 (디스크 읽기, 네트워크 패킷, 마우스 이동, 키 누르기 등)를 수집 할 때까지 기다려야하므로 속도가 느립니다.
더 빠른 솔루션은 하드웨어 난수 생성기입니다. 이미 마더 보드에 내장되어있을 수 있습니다. hw_random 문서 에서 확인하고 사용 방법에 대한 지침을 확인 하십시오. rng-tools 패키지에는 하드웨어로 생성 된 엔트로피를에 공급하는 데몬이 포함되어 /dev/random
있습니다.
시스템에서 HRNG를 사용할 수없고 성능을 위해 엔트로피 강도를 기꺼이 희생하려는 경우의 데이터를 사용하여 좋은 PRNG를 시드 /dev/random
하고 PRNG가 많은 작업을 수행하도록 할 수 있습니다. SP800-90 에는 NIST가 승인 한 PRNG가 몇 가지 간단하게 구현되어 있습니다.
답변
Java 8을 사용하여 Linux 호출 SecureRandom.getInstanceStrong()
에서 NativePRNGBlocking
알고리즘을 제공 한다는 것을 알았습니다 . 이것은 종종 몇 초 동안 차단하여 몇 바이트의 소금을 생성합니다.
NativePRNGNonBlocking
대신 명시 적으로 요청하도록 전환 했으며 이름에서 예상 한대로 더 이상 차단되지 않았습니다. 나는 이것이 보안의 의미가 무엇인지 전혀 모른다. 아마도 비 차단 버전은 사용되는 엔트로피의 양을 보장 할 수 없습니다.
업데이트 : 좋아, 나는 이 훌륭한 설명을 발견했다 .
간단히 말해서 블로킹을 피하려면을 사용하십시오 new SecureRandom()
. 이것은를 사용 /dev/urandom
하지 않으며 기본적으로 안전합니다 /dev/random
. 게시물에서 : “/ dev / random을 호출하려는 유일한 시간은 시스템이 처음 부팅되고 엔트로피가 아직 누적되지 않은 경우입니다.”
SecureRandom.getInstanceStrong()
절대적으로 가장 강력한 RNG를 제공하지만 많은 차단이 영향을 미치지 않는 상황에서만 사용하는 것이 안전합니다.