De acordo com a documentação , os diferentes algoritmos usados pelo SecureRandom são, em ordem de preferência:
- Na maioria dos sistemas * NIX
- NativePRNG
- SHA1PRNG
- NativePRNGBlocking
- NativePRNGNonBlocking
- Em sistemas Windows
- SHA1PRNG
- Windows-PRNG
Desde que você perguntou sobre o Linux, estou ignorando a implementação do Windows, e também o SunPKCS11, que só está realmente disponível no Solaris, a menos que você o tenha instalado - e você não perguntaria isso.
De acordo com a mesma documentação, o que esses algoritmos usam são
SHA1PRNG
A propagação inicial é atualmente feita por meio de uma combinação de atributos do sistema e o dispositivo de coleta de entropia java.security.
NativePRNG
nextBytes()
usa /dev/urandom
generateSeed()
usos/dev/random
NativePRNGBlocking
nextBytes()
e generateSeed()
uso/dev/random
NativePRNGNonBlocking
nextBytes()
e generateSeed()
uso/dev/urandom
Isso significa que, se você usar SecureRandom random = new SecureRandom()
, ele desce essa lista até encontrar uma que funcione, que normalmente será NativePRNG. E isso significa que ele se propaga a partir de /dev/random
(ou usa isso se você gerar explicitamente uma semente), e então usa /dev/urandom
para obter os próximos bytes, ints, double, booleanos, o que você tem.
Como /dev/random
está bloqueando (ele bloqueia até ter entropia suficiente no pool de entropia), isso pode impedir o desempenho.
Uma solução para isso é usar algo como Haveged para gerar entropia suficiente, outra solução está sendo usada /dev/urandom
. Embora você possa definir isso para toda a jvm, uma solução melhor é fazer isso para essa instância específica do SecureRandom
usando SecureRandom random = SecureRandom.getInstance("NativePRNGNonBlocking")
. Observe que esse método pode gerar uma NoSuchAlgorithmException se NativePRNGNonBlocking, portanto, esteja preparado para retornar ao padrão.
SecureRandom random;
try {
random = SecureRandom.getInstance("NativePRNGNonBlocking");
} catch (NoSuchAlgorithmException nsae) {
random = new SecureRandom();
}
Observe também que em outros sistemas * nix, /dev/urandom
pode se comportar de maneira diferente .
É /dev/urandom
aleatório o suficiente?
A sabedoria convencional diz que apenas /dev/random
é aleatória o suficiente. No entanto, algumas vozes diferem. Em "A maneira correta de usar o SecureRandom" e "Mitos sobre / dev / urandom" , argumenta-se que isso /dev/urandom/
é igualmente bom.
Os usuários na pilha de Segurança da informação concordam com isso . Basicamente, se você precisar perguntar, tudo /dev/urandom
bem para o seu propósito.