Como lidar com um lento gerador SecureRandom?

165

Se você quiser números aleatórios criptograficamente fortes em Java, use SecureRandom. Infelizmente, SecureRandompode ser muito lento. Se ele usa /dev/randomno Linux, pode bloquear a espera de entropia suficiente para se acumular. Como você evita a penalidade de desempenho?

Alguém já usou Uncommon Maths como uma solução para este problema?

Alguém pode confirmar que esse problema de desempenho foi resolvido no JDK 6?

David G
fonte
Parece que isso está relacionado à lentidão do SecureRandom.generateSeed () . Existe um defeito rejeitado que explica a lentidão e uma solução alternativa: JDK-6521844: O SecureRandom trava nos sistemas Linux
AlikElzin-kilaka 29/11
Confira / dev / urandom (não / dev / random). Considere apenas obter um gerador de números aleatórios da urandom se houver um problema de bloqueio.
jcalfee314
Janelas relacionadas: stackoverflow.com/questions/49322948/… #
patrikbeno

Respostas:

79

Se você quiser dados aleatórios verdadeiros, infelizmente precisará esperar por eles. Isso inclui a semente de um SecureRandomPRNG. O Uncommon Maths não pode reunir dados aleatórios verdadeiros com mais rapidez do que SecureRandom, embora possa se conectar à Internet para baixar dados de sementes de um site específico. Meu palpite é que é improvável que seja mais rápido do /dev/randomque o local disponível.

Se você deseja um PRNG, faça algo assim:

SecureRandom.getInstance("SHA1PRNG");

Quais strings são suportadas dependem do SecureRandomprovedor SPI, mas você pode enumerá-las usando Security.getProviders()e Provider.getService().

A Sun gosta de SHA1PRNG, por isso está amplamente disponível. Não é tão rápido quanto os PRNGs, mas os PRNGs serão apenas trituradores de números, não bloqueando a medição física da entropia.

A exceção é que, se você não ligar setSeed()antes de obter dados, o PRNG se propagará uma vez na primeira vez que você ligar next()ou nextBytes(). Geralmente, isso é feito usando uma quantidade bastante pequena de dados aleatórios verdadeiros do sistema. Essa chamada pode bloquear, mas tornará sua fonte de números aleatórios muito mais segura do que qualquer variante de "hash da hora atual junto com o PID, adicione 27 e espere o melhor". Porém, se tudo o que você precisa é de números aleatórios para um jogo ou se você deseja que o stream possa ser repetido no futuro usando a mesma semente para fins de teste, uma semente insegura ainda será útil.

Steve Jessop
fonte
A Uncommons Maths baixa apenas dados da Internet para propagação, não retorna esses dados aleatórios ao gerar números aleatórios.
Dan Dyer
O mesmo com o SecureRandom - o / dev / urandom é apenas para propagação.
Avid
Sim. Quando o interlocutor diz "se você quiser um número aleatório, use o SecureRandom - isso pode ser lento", pensei que talvez ele estivesse usando o getSeed para tudo e esgotando o pool de entropia. A correção não é obter o JDK 6, é usar o SecureRandom do jeito que ele é planejado ;-) #
Steve
@ Dan Dyer - Corrigi meu comentário sobre Uncommon Maths. Eu dei uma olhada na sua página, então sabia que, por "números aleatórios", eu quis dizer "por sua semente" e não "retornar ao usuário". Mas você está certo de que não é o que eu disse ...
Steve Jessop
"está amplamente disponível". Não está incluído em todos os JDK compatíveis? Ele está na lista de nomes padrão de segurança java ... ( docs.oracle.com/javase/8/docs/technotes/guides/security/… )
Sean Reilly
176

Você deve poder selecionar o / dev / urandom mais rápido, mas um pouco menos seguro, no Linux usando:

-Djava.security.egd=file:/dev/urandom

No entanto, isso não funciona com o Java 5 e posterior ( Java Bug 6202721 ). A solução alternativa sugerida é usar:

-Djava.security.egd=file:/dev/./urandom

(observe o extra /./)

Thomas Leonard
fonte
24
Observe que o relatório de bug do Java diz "Não é um defeito". Em outras palavras, mesmo que o padrão seja /dev/urandom, a Sun a trata como uma sequência mágica e a usa de /dev/randomqualquer maneira, então você precisa fingir. Quando um file:URL não é um file:URL? Sempre que a Sun decide que não é :-(
Jim Garrison
6
Depois de passar muito tempo investigando isso, parece que a configuração normal, mesmo com file:/dev/urandomdefinida no -Djava.security.egdou no securerandom.sourcearquivo java.security, /dev/random/ainda é lida sempre que SecureRandom.getSeed()(ou setSeed()é chamada). A solução alternativa com file:/dev/./urandomresultados em não ler /dev/randomnada (confirmada com strace) #
matt b
7
/dev/urandomnão é menos seguro do que /dev/randomquando implementado com um CSPRNG moderna: en.wikipedia.org/wiki//dev/random#FreeBSD
Lapo
Eu acho que o principal medo /dev/urandom/é o que acontece se você usá-lo para gerar segredos em um novo hardware pronto para uso, o que pode estar em um estado bastante previsível. /dev/urandom/não bloqueará a entropia, mesmo que esse seja o caso em que você deveria. A situação é ainda pior se o segredo for persistente, como se a primeira coisa que seu dispositivo fizesse na primeira inicialização fosse gerar um par de chaves público-privado. Fora dessas situações assustadoras, um bem /dev/urandomé melhor do que usar os SecureRandomalgoritmos comuns de qualquer maneira.
18714 Steve Jobs (
1
Qual deles está correto? -Djava.security.egd = file: / dev /./ urandom ou file: /// dev / urandom @mattb
Aarish Ramesh
35

No Linux, a implementação padrão para SecureRandomé NativePRNG(código fonte aqui ), que tende a ser muito lenta. No Windows, o padrão é SHA1PRNGque, como outros apontaram, você também pode usar no Linux se especificá-lo explicitamente.

NativePRNGdifere de SHA1PRNGe Uncommons AESCounterRNG do Maths por receber continuamente entropia do sistema operacional (lendo em /dev/urandom). Os outros PRNGs não adquirem nenhuma entropia adicional após a semeadura.

O AESCounterRNG é cerca de 10x mais rápido que o IIRC SHA1PRNG, ele próprio, duas ou três vezes mais rápido que NativePRNG.

Se você precisar de um PRNG mais rápido que adquira entropia após a inicialização, veja se consegue encontrar uma implementação Java do Fortuna . O PRNG principal de uma implementação Fortuna é idêntico ao usado pelo AESCounterRNG, mas também existe um sistema sofisticado de pool de entropia e nova propagação automática.

Dan Dyer
fonte
Este link não está funcionando. uncommons-maths.dev.java.net/nonav/api/org/uncommons/maths/… . Existe algum lugar em que eu possa ver isso?
UVM
@Unni Apenas atualizei o link. Observe que as reivindicações de desempenho que fiz nesta resposta podem não ser mais válidas. Eu acho que as coisas podem ter melhorado nas versões recentes do Java e pode haver diferenças no desempenho entre plataformas (por exemplo, Windows x Liux).
Dan Dyer
Eu estava apenas executando um exemplo de SecureRandom com um MessageDigest e o fiz com um código hexadecimal. Toda a operação no PC com Windows 7 levou 33 milissegundos. É um problema. Usei SHA1PRNG.SecureRandom prng = SecureRandom.getInstance ("SHA1PRNG"); String randomNum = new Inteiro (prng.nextInt ()) .toString (); MessageDigest sha = MessageDigest.getInstance ("SHA-1"); resultado = sha.digest (randomNum.getBytes ()); str = hexEncode (resultado);
UVM
24

Muitas distribuições Linux (principalmente baseadas no Debian) configuram o OpenJDK para uso /dev/randomem entropia.

/dev/random por definição, é lento (e pode até bloquear).

A partir daqui, você tem duas opções para desbloqueá-lo:

  1. Melhorar a entropia, ou
  2. Reduza os requisitos de aleatoriedade.

Opção 1, melhorar a entropia

Para obter mais entropia /dev/random, tente o daemon protegido . É um daemon que coleta continuamente a entropia HAVEGE e funciona também em um ambiente virtualizado porque não requer nenhum hardware especial, apenas a própria CPU e um relógio.

No Ubuntu / Debian:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

No RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Opção 2. Reduzir os requisitos de aleatoriedade

Se, por algum motivo, a solução acima não ajudar ou você não se importar com a aleatoriedade criptograficamente forte, você pode alternar para o /dev/urandomque é garantido para não bloquear.

Para fazer isso globalmente, edite o arquivo jre/lib/security/java.securityem sua instalação Java padrão para usar /dev/urandom(devido a outro bug, ele precisa ser especificado como /dev/./urandom).

Como isso:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

Então você nunca precisará especificá-lo na linha de comando.


Nota: Se você faz criptografia, precisa de uma boa entropia. Caso em questão - o problema do PRNG no Android reduziu a segurança das carteiras Bitcoin.

rustyx
fonte
A sua resposta foi positiva, mas " /dev/randomé por definição lenta (e pode até bloquear)" está errada; depende inteiramente da configuração do sistema. Máquinas mais recentes podem ter, por exemplo, um RNG rápido na CPU que pode ser usada, e máquinas BSD geralmente têm a mesma implementação para /dev/randome /devl/urandom. Ainda assim, você provavelmente não deve confiar em /dev/random ser rápido, necessariamente. Nas VMs, convém instalar o conjunto de ferramentas do cliente na VM do cliente para poder usar o RNG do sistema operacional host.
Maarten Bodewes
17

Eu tive um problema semelhante com as chamadas para SecureRandombloqueio por cerca de 25 segundos por vez em um servidor Debian decapitado. Eu instalei o havegeddaemon para garantir a /dev/randommanutenção, em servidores sem cabeça, você precisa de algo assim para gerar a entropia necessária. Minhas ligações para SecureRandomagora talvez levem milissegundos.

trovão
fonte
4
O apt-get install haveged e o update-rc.d possuem padrões
Rod Lima
11

Se você deseja uma aleatoriedade verdadeiramente "criptograficamente forte", precisará de uma fonte de entropia forte. /dev/randomé lento porque precisa aguardar os eventos do sistema para coletar entropia (leituras de disco, pacotes de rede, movimento do mouse, pressionamentos de teclas etc.).

Uma solução mais rápida é um gerador de números aleatórios de hardware. Você já pode ter um embutido na sua placa-mãe; consulte a documentação do hw_random para obter instruções sobre como descobrir se você a possui e como usá-la. O pacote rng-tools inclui um daemon que alimentará a entropia gerada por hardware /dev/random.

Se um HRNG não estiver disponível no seu sistema e você estiver disposto a sacrificar a força da entropia para obter desempenho, deseje gerar um bom PRNG com dados de /dev/randome deixar que o PRNG faça a maior parte do trabalho. Existem vários PRNGs aprovados pelo NIST listados no SP800-90 que são fáceis de implementar.

Chris Kite
fonte
Bom ponto, mas meu código faz parte de um aplicativo comercial. Não tenho nenhum controle sobre o ambiente do servidor. Acho que os servidores de destino sempre estão sem mouse e teclado e dependem inteiramente de E / S de disco e rede para entropia, o que provavelmente é o problema raiz.
David G
3
Eu descobri que / dev / random era dependente de eventos do sistema, assim como uma solução temporária, eu só mudou o meu mouse e para trás enquanto a minha RAN test ....
David K
Esse hub 82802 para o chipset i820 era dolorosamente lento (RIP). Estou surpreso que você possa reunir qualquer coisa útil com isso. Eu acho que gastei mais tempo bloqueando isso do que coletando octetos.
JWW
6

Usando o Java 8, descobri que na chamada do Linux SecureRandom.getInstanceStrong()me daria o NativePRNGBlockingalgoritmo. Isso geralmente bloqueia por muitos segundos para gerar alguns bytes de sal.

Em NativePRNGNonBlockingvez disso, mudei para pedir explicitamente e, como esperado, o nome não está mais bloqueado. Não tenho ideia de quais são as implicações de segurança disso. Presumivelmente, a versão sem bloqueio não pode garantir a quantidade de entropia usada.

Atualização : Ok, achei esta excelente explicação .

Em poucas palavras, para evitar o bloqueio, use new SecureRandom(). Isso usa /dev/urandom, o que não bloqueia e é basicamente tão seguro quanto /dev/random. Da postagem: "A única vez em que você deseja chamar / dev / random é quando a máquina é inicializada pela primeira vez e a entropia ainda não foi acumulada".

SecureRandom.getInstanceStrong() fornece o RNG mais forte, mas é seguro apenas para uso em situações em que muitos bloqueios não afetam você.

Lachlan
fonte
1
Permitiria apenas getInstanceStrong()chaves de longo prazo, como as dos certificados TLS. E mesmo assim, prefiro usar new SecureRandom()ou um gerador de pares de chaves compatível com FIPS ou gerador de números aleatórios. Então, sim, isso fornece uma resposta, se /dev/urandom não bloquear: no final, ainda depende da entropia do sistema; mas é um conselho muito bom em geral . Se houver /dev/urandombloqueios, talvez seja necessário corrigir a origem do problema e não o aplicativo Java.
Maarten Bodewes
5

Existe uma ferramenta (pelo menos no Ubuntu) que alimenta aleatoriedade artificial em seu sistema. O comando é simplesmente:

rngd -r /dev/urandom

e você pode precisar de um sudo na frente. Se você não possui o pacote rng-tools, será necessário instalá-lo. Eu tentei isso, e definitivamente me ajudou!

Fonte: mundo vs matt

David K
fonte
2
Isso é um tanto perigoso, pois desativa completamente a estimativa do nível de entropia do kernel do Linux, em todo o sistema. Acho que, para fins de teste (lê-se: Jenkins executando o testinguite de um aplicativo), usar /dev/./urandom é bom, mas na produção não é.
mirabilos
Esta é realmente a única solução que funcionou para mim. Eu tive um problema de "entropia insuficiente" ao criar um projeto Android com Gradle no Jenkins CI, e passar um parâmetro para a compilação não ajudou.
Slav
Eu tive que combinar sudo rngd -r /dev/urandomcom sudo apt install rng-toolsem xenial
MrMesees
5

Eu enfrentei o mesmo problema . Depois de pesquisar no Google com os termos de pesquisa certos, me deparei com este belo artigo no DigitalOcean .

haveged é uma solução potencial sem comprometer a segurança.

Estou apenas citando a parte relevante do artigo aqui.

Com base no princípio HAVEGE e anteriormente em sua biblioteca associada, o Haveged permite gerar aleatoriedade com base em variações no tempo de execução do código em um processador. Como é quase impossível que um pedaço de código leve o mesmo tempo exato para ser executado, mesmo no mesmo ambiente no mesmo hardware, o tempo de execução de um ou vários programas deve ser adequado para propagar uma fonte aleatória. A implementação simplificada semeia a fonte aleatória do seu sistema (geralmente / dev / random) usando diferenças no contador de carimbo de data / hora (TSC) do seu processador depois de executar um loop repetidamente

Como instalar haveged

Siga as etapas deste artigo. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

Eu publiquei aqui

tão aleatório
fonte
5

O problema que você referenciou /dev/randomnão está no SecureRandomalgoritmo, mas na fonte de aleatoriedade que ele usa. Os dois são ortogonais. Você deve descobrir qual dos dois está atrasando você.

A página incomum de matemática que você vinculou menciona explicitamente que eles não estão abordando a fonte da aleatoriedade.

Você pode experimentar diferentes provedores JCE, como o BouncyCastle, para verificar se a implementação deles SecureRandomé mais rápida.

Uma breve pesquisa também revela patches do Linux que substituem a implementação padrão pelo Fortuna. Não sei muito mais sobre isso, mas você pode investigar.

Também devo mencionar que, embora seja muito perigoso usar um SecureRandomalgoritmo mal implementado e / ou uma fonte aleatória, você pode rolar seu próprio provedor JCE com uma implementação customizada de SecureRandomSpi. Você precisará passar por um processo com a Sun para assinar seu provedor, mas na verdade é bastante direto; eles só precisam que você envie por fax um formulário informando que você conhece as restrições de exportação dos EUA em bibliotecas de criptografia.

ykaganovich
fonte
Esses provedores JCE diferentes são úteis apenas se eles usarem outra fonte de entropia, o que basicamente significa que eles precisam usar um pedaço de hardware específico, como um HSM. Caso contrário, eles têm a mesma probabilidade de sofrer lentidão, dependendo da quantidade de entropia que extraem do sistema.
Maarten Bodewes
3

Use o aleatório seguro como fonte de inicialização para um algoritmo recorrente; você poderia usar um twister de Mersenne para o trabalho em massa, em vez daquele no UncommonMath, que já existe há algum tempo e provou ser melhor do que outros

http://en.wikipedia.org/wiki/Mersenne_twister

Atualize de vez em quando o aleatório seguro usado para a inicialização; por exemplo, você pode ter um aleatório seguro gerado por cliente, usando um gerador pseudo-aleatório mersenne twister por cliente, obtendo um grau de randomização alto o suficiente

Lorenzo Boccaccia
fonte
2
Esta resposta está errada: o twister de Mersenne não é um gerador seguro de números aleatórios. Seria um bom algoritmo para Random, mas não para SecureRandom.
Maarten Bodewes
3

De acordo com a documentação , os diferentes algoritmos usados ​​pelo SecureRandom são, em ordem de preferência:

  • Na maioria dos sistemas * NIX
    1. NativePRNG
    2. SHA1PRNG
    3. NativePRNGBlocking
    4. NativePRNGNonBlocking
  • Em sistemas Windows
    1. SHA1PRNG
    2. 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.

SQB
fonte
2

Eu mesmo não enfrentei esse problema, mas geraria um encadeamento no início do programa que imediatamente tenta gerar uma semente e depois morre. O método que você chama de randoms se unirá a esse encadeamento se estiver ativo; portanto, a primeira chamada será bloqueada apenas se ocorrer muito cedo na execução do programa.

usuario
fonte
É um truque bastante extremo, mas pode funcionar; não se diz que o PRNG usado possa não usar material de semente adicional que ainda pode levar ao bloqueio. O uso de um número aleatório diferente que forneça ou fixe a entropia no sistema deve ser fortemente preferido. Como pode pelo menos fornecer uma solução temporária, votei a resposta.
Maarten Bodewes
2

Minha experiência foi apenas com a lenta inicialização do PRNG, não com a geração de dados aleatórios depois disso. Tente uma estratégia de inicialização mais ávida. Como sua criação é cara, trate-a como um singleton e reutilize a mesma instância. Se houver muita contenção de encadeamentos em uma instância, agrupe-os ou torne-os encadeados locais.

Não comprometa a geração aleatória de números. Uma fraqueza compromete toda a sua segurança.

Não vejo muitos geradores baseados em decaimento atômico do COTS, mas existem vários planos para eles, se você realmente precisa de muitos dados aleatórios. Um site que sempre tem coisas interessantes para se olhar, incluindo o HotBits, é o Fourmilab de John Walker.

erickson
fonte
1
Eu sempre me perguntei sobre isso, já que os produtos de decaimento hadrônico da tau quase atingem o ideal de uma fonte aleatória, simplesmente não consigo me livrar do meu desejo de usá-lo em vez de ferramentas algorítmicas. Para o propósito da operação, decidi há muito tempo que algum tempo de front-end é endêmico para todas as ferramentas seguras. Se alguém vai precisar de um randomizador, que pode ser chamado no construtor e lembre-se de construir um no tempo de carregamento da página, ele será enterrado sob a troca avl e, mesmo sendo exigente como eu, não será notado.
222 Nicholas Nicholas Nicholas
Os chipsets Intel 8xx (e provavelmente muitos outros) possuem um RNG de hardware que usa ruído térmico, um efeito quântico verdadeiramente imprevisível. Os Módulos de plataforma confiáveis ​​também podem conter RNGs de hardware, mas infelizmente o do meu laptop não.
21410
Depende do RNG específico se for semeado uma vez ou se for repetido após algum tempo. O NIST especifica os PRNGs que se propagam novamente, mas muitas implementações de software não. Reestruturar o código em torno de um singleton é uma ideia horrível, especialmente em implementações multithread; é melhor corrigir a fonte do problema: a propagação lenta devido à falta de entropia. Se você usar um singleton, use-o para fornecer sementes para outras implementações do SecureRandom totalmente determinísticas. Esse tipo de design provavelmente requer bastante conhecimento.
Maarten Bodewes
@MaartenBodewes Esses são bons pontos. Se a implementação é aquela que bloqueia a espera da entropia do sistema, acho que tratá-la como um singleton no seu aplicativo não é uma ideia horrível, pois a fonte subjacente é efetivamente um singleton. Mas usar essa instância para propagar outras é uma boa sugestão, mesmo que complexa. Não tenho certeza, mas acho que o fornecedor da Sun (e depois da Oracle) SecureRandommudou algumas vezes nos últimos 10 anos em sua coleta de entropia.
Erickson
Tenho certeza de que ele mudou algumas vezes, tanto que não tentarei colocar todas as alterações neste comentário :). É menos provável que um lento SecureRandomainda seja um problema, mas a baixa entropia em um sistema sempre será um problema. Usar um singleton criará um código fortemente acoplado, que é um antipadrão de design. Portanto, deve ser usado com extremo cuidado; de preferência, você teria que reverter todas as referências no código para corrigir o problema.
Maarten Bodewes
2

Parece que você deve ser mais claro sobre seus requisitos de RNG. O requisito de RNG criptográfico mais forte (como eu o entendo) seria que, mesmo que você conheça o algoritmo usado para gerá-los e conheça todos os números aleatórios gerados anteriormente, não poderá obter informações úteis sobre nenhum dos números aleatórios gerados no futuro, sem gastar uma quantidade impraticável de poder de computação.

Se você não precisar dessa garantia completa de aleatoriedade, provavelmente haverá trocas de desempenho apropriadas. Eu tenderia a concordar com a resposta de Dan Dyer sobre o AESCounterRNG da Uncommons-Maths ou Fortuna (um de seus autores é Bruce Schneier, especialista em criptografia). Eu também nunca usei, mas as idéias parecem respeitáveis ​​à primeira vista.

Eu pensaria que se você pudesse gerar uma semente aleatória inicial periodicamente (por exemplo, uma vez por dia ou hora ou qualquer outra coisa), poderia usar uma cifra de fluxo rápido para gerar números aleatórios a partir de pedaços sucessivos do fluxo (se a cifra de fluxo usar XOR, apenas passe um fluxo de nulos ou pegue os bits XOR diretamente). EStream do ECRYPTO projeto possui muitas informações boas, incluindo benchmarks de desempenho. Isso não manteria a entropia entre os pontos no tempo em que você o reabasteceria; portanto, se alguém conhecesse um dos números aleatórios e o algoritmo usado, tecnicamente seria possível, com muita capacidade de computação, interromper a cifra do fluxo e adivinhe seu estado interno para poder prever números aleatórios futuros. Mas você teria que decidir se esse risco e suas conseqüências são suficientes para justificar o custo de manutenção da entropia.

Edit: aqui estão algumas notas de curso criptográficas sobre RNG que encontrei na rede que parecem muito relevantes para este tópico.

Jason S
fonte
1
"Fortuna (um dos autores é Bruce Schneier, um especialista em criptografia)" - e o outro é Niels Ferguson, um especialista em criptografia :-)
Steve Jessop
2

Se o seu hardware suportar, tente usar o Java RdRand Utility, do qual sou o autor.

Ele é baseado nas RDRANDinstruções da Intel e é cerca de 10 vezes mais rápido do que SecureRandome sem problemas de largura de banda para a implementação de grandes volumes.


Observe que essa implementação funciona apenas nas CPUs que fornecem a instrução (ou seja, quando o rdrandsinalizador do processador está definido). Você precisa instanciar explicitamente isso através do RdRandRandom()construtor; nenhum específico Providerfoi implementado.

user2781824
fonte
3
Você pode ler people.umass.edu/gbecker/BeckerChes13.pdf e não se esqueça de nunca usar apenas dados Intel RDRAND. Sempre misture-o com outros dados imprevisíveis, como a saída de uma cifra de fluxo aRC4 (semeada em / dev / urandom e com os primeiros KiB de saída descartados por seu viés conhecido).
mirabilos
+1 mirabilos. Eu acho que RDRANDé uma boa fonte, mas não é confiável. Definitivamente precisa ser uma contribuição de muitos para um colecionador (sem ofensa a David Johnston).
JWW
Votei, corrigi o link e forneci algumas informações básicas. Se você não concordar, reverta a edição.
Maarten Bodewes
1

Outra coisa a se observar é a propriedade securerandom.source no arquivo lib / security / java.security

Pode haver um benefício no desempenho ao usar / dev / urandom em vez de / dev / random. Lembre-se de que se a qualidade dos números aleatórios for importante, não comprometa a segurança.

Diastrofismo
fonte