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/urandompara obter os próximos bytes, ints, double, booleanos, o que você tem.
Como /dev/randomestá 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 SecureRandomusando 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/urandompode se comportar de maneira diferente .
É /dev/urandomaleató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/urandombem para o seu propósito.