Geração de par de chaves RSA 2048: via openssl 0.5s via gpg 30s, por que a diferença?

9

Geração de pares de chaves RSA 2048: via openssl 0.5s via gpg 30s, por que a diferença Existem vários programas que podem gerar pares de chaves públicos / privados RSA

O GnuPG / OpenPGP, por exemplo, tem um wizzard sendo invocado via

gpg --gen-key

O OpenSSL pode gerar um par de chaves usando essas linhas de comando

openssl genrsa -out testkey.private 2048
openssl rsa -in testkey.private -pubout -out testkey.public

pela mesma coisa, que está gerando um par de chaves RSA 2048 bit, posso perceber - na mesma máquina - tempos muito diferentes.

opensslgera um par de chaves em cerca de 0,5s
gpgleva cerca de 30 e até anúncios "movem o mouse para gerar aleatoriedade / entropia"

A diferença pode ser explicada? Eu sei que o gpg faz um pouco mais do que apenas a criação da chave RSA, mas eu escolho especificamente a opção (4)

Selecione o tipo de chave que você deseja:
   (1) RSA e RSA (padrão)
   (2) DSA e Elgamal
   (3) DSA (somente assinatura)
   (4) RSA (somente sinal)
Sua seleção?

Portanto, realmente a única coisa gerada é um par de chaves RSA de 2048 bits. No entanto, a diferença horária está diminuindo 30 segundos?

Para mim, parece que o gpg está perdendo tempo desnecessariamente ou o OpenSSL não está esperando tempo suficiente e, portanto, cria chaves inseguras.

Minha pergunta é o que poderia explicar a diferença?

Atualizar

A criação do RSA deve ter como entrada alguma aleatoriedade. Por isso, para ter certeza de que o openssl veloz não é simplesmente o resultado do uso de alguma aleatoriedade armazenada, eu o executo várias vezes

time bash -c "para i em {1..50}; do openssl genrsa -out / dev / null 2048; pronto;"

que produz

0m16.577s reais
usuário 0m16.309s
sys 0m0.092s

ou seja, para 50 chaves RSA de 2048 bits (presumo que exista muita entropia / aleatoriedade), o openssl ainda precisa apenas de 16 segundos. Minha suposição aqui seria, portanto, a "resposta" que openssl deve ser quebrada. Afinal, desconfio que meu Linux (um kernel 3.2.0-59) tenha se tornado tão bom em gerar aleatoriedade.

Talvez a diferença seja simplesmente o uso do openssl /dev/urandome o gpg /dev/randomque, se verdadeiro, poderiam explicar a diferença de horário. Meu problema é que eu não sei como descobrir isso, para verificar isso.

update2

Para testar a fonte aleatória do openssl, usei

strace -xe trace = arquivo, ler, escrever, fechar openssl genrsa -out testkey5.private 2048 2> & 1 | grep random -A1

que produz

open ("/ dev / urandom", O_RDONLY | O_NOCTTY | O_NONBLOCK) = 4
read (4, "\ x21 \ xd8 \ xaa \ xf1 \ x2b \ x5f \ x4a \ x89 \ x5d \ x6c \ x58 \ x82 \ xc1 \ x88 \ x21 \ x04 \ xfa \ x5b \ x18 \ x98 \ x8a \ x34 \ x2b \ xe3 \ xf3 \ xc0 \ xb1 \ xef \ xfb \ x44 \ x15 \ x09 ", 32) = 32

então parece que 32 bytes de /dev/urandom(não o "melhor" /dev/random) são suficientes para o par de chaves RSA de 2048 bits no openssl. Portanto, é tão rápido!

Medidas

A geração de pares de chaves RSA de 2048 bits significa

  • Apenas 32 bytes /dev/urandom(usando o openssl)
  • 300 bytes de /dev/random(usando o openPGP GNU Privacy Guard)

isso explica, é claro, a diferença de horário!

humanidade e paz
fonte

Respostas:

10

O GnuPG consome vários bytes /dev/randompara cada byte aleatório que ele realmente usa. Você pode facilmente verificar isso com este comando:

start cmd:> strace -e trace=open,read gpg --armor --gen-random 2 16 2>&1 | tail
open("/etc/gcrypt/rngseed", O_RDONLY)   = -1 ENOENT (No such file or directory)
open("/dev/urandom", O_RDONLY)          = 3
read(3, "\\\224F\33p\314j\235\7\200F9\306V\3108", 16) = 16
open("/dev/random", O_RDONLY)           = 4
read(4, "/\311\342\377...265\213I"..., 300) = 128
read(4, "\325\3\2161+1...302@\202"..., 172) = 128
read(4, "\5[\372l\16?\...6iY\363z"..., 44) = 44
open("/home/hl/.gnupg/random_seed", O_WRONLY|O_CREAT, 0600) = 5
cCVg2XuvdjzYiV0RE1uzGQ==
+++ exited with 0 +++

Para gerar 16 bytes de entropia de alta qualidade, o GnuPG lê 300 bytes /dev/random.

Isso é explicado aqui: Arquitetura de subsistema de número aleatório

O Linux armazena no máximo 4096 bytes (consulte cat /proc/sys/kernel/random/poolsize) de entropia. Se um processo precisar de mais do que o disponível (consulte cat /proc/sys/kernel/random/entropy_avail), o uso da CPU se tornará mais ou menos irrelevante, pois a velocidade de alimentação do pool de entropia do kernel se torna o fator relevante.

Hauke ​​Laging
fonte
Impressionante. Obrigado pela compreensão. Eu acho que isso praticamente esclarece a questão! Parece que enquanto o openssl está satisfeito com 32 bytes de menos qualidade, o /dev/urandomgpg diz "1 byte /dev/randomnão é bom o suficiente para 1 byte de forma aleatória". Isso não significa que as chaves openssl são mais propensas a "pouca aleatoriedade" em comparação com os gpg?
humanityANDpeace
1
@humanityANDpeace Randomness é uma discussão sem fim. Há pouco tempo, o "usuário mestre" deste site fez a afirmação de que /dev/urandomera boa o suficiente para fins de criptografia. Na lista de discussão do GnuPG, ele provavelmente seria motivo de riso por isso. AFAIK é impossível provar que certos dados são puramente aleatórios. Você pode encontrar não aleatoriedade, mas apenas onde você procura exatamente esse padrão.
Hauke ​​Laging
sim entendo :) Ainda o fato de o gpg usar 300 bytes de /dev/randomenquanto o openssl usa apenas 32 bytes de /dev/urandomparece sugerir um risco potencial à segurança do usuário cauteloso, como deseja um par de chaves RSA de 2048 bits. Eu, portanto, optar por gpg. 32bytes parece terrivelmente pequeno
humanidadeANDpeace
2
@HaukeLaging O "usuário mestre" deste site recebeu esse conselho do "usuário mestre" de Segurança da Informação e Criptografia , com uma explicação que faz sentido (diferentemente da computação do tamanho do pool de entropia do Linux, o que não acontece). Um rand de / dev / urandom é seguro para uma chave de login? "A resposta curta é sim. A resposta longa também é sim.
Gilles 'SO- stop be evil'
2
A leitura de 32 bytes de um CSPRNG bem distribuído fornece 256 bits de segurança (o que é muito ). Uma chave RSA-2048 bits oferece apenas cerca de 112 bits de segurança. A única propriedade duvidosa de a /dev/urandomé que (no linux) não é bloqueada antes de ser propagada diretamente após a inicialização. Uma vez semeado, permanecerá seguro para sempre.
CodesInChaos
7

Sua sugestão de que essa diferença ocorre porque opensslusa / dev / urandom e gpgusos /dev/randomestá correto.

Você pode assistir a entropia disponível diminuindo enquanto gera chaves gpgusando:

watch -n 1 cat /proc/sys/kernel/random/entropy_avail

Eu usei um programa para gerar a descrição das etapas para a configuração de um cartão inteligente OpenGPGgpg , então tive que executar gpgvárias vezes até que tudo desse certo. Após as execuções iniciais, notei que /dev/randomnão haveria entropia suficiente e o gpg ficaria parado aguardando a acumulação de nova entropia.

Escrevi um pequeno programa para fornecer dados não aleatórios extras e, ao fazê-lo gpg, não "pararia", mas geraria as chaves quase imediatamente: bom para testar o script para executar corretamente, mas é claro que não é algo que você deve fazer ao gerar seu real chaves.

O programa para acelerar gpg( não use em situações reais ):

# For testing purposes only 
# DO NOT USE THIS, tHIS DOES NOT PROVIDE ENTROPY TO /dev/random

import fcntl
import time
import struct

RNDADDENTROPY=0x40085203

while True:
    random = "3420348024823049823-984230942049832423l4j2l42j"
    t = struct.pack("ii32s", 8, 32, random)
    with open("/dev/random", mode='wb') as fp:
        # as fp has a method fileno(), you can pass it to ioctl
        res = fcntl.ioctl(fp, RNDADDENTROPY, t)
        time.sleep(0.001)

Quando eu executo isso enquanto assisto entropy_avail, vejo a entropia disponível subir para mais de 3800.

Anthon
fonte
Obrigado pela resposta. Ainda estou ansioso para testar o gpg, que infelizmente é menos adaptável e mais interativo. .. Ainda. Você tem certeza de que a chamada repetida catpor si só ainda não drena a entropia? Você tem alguma evidência ou fonte que diz /dev/randomque o uso de gpg aperfeiçoaria a resposta? Por fim, isso também significa que o openssl gera pares de chaves RSA de qualidade inferior ao gqg?
humanityANDpeace
@humanityANDpeace É possível (embora menos óbvio) usar o GnuPG no modo batch. Procure Unattended key generationno arquivo /usr/share/doc/packages/gpg2/DETAILS(ou o que quer que esteja na sua distribuição). A /dev/randomevidência está na minha resposta.
Hauke ​​Laging 16/03/14
@humanityANDpeace A resposta de Hauke ​​é mais direta, mas eu encontrei várias referências a ela enquanto pesquisava como configurar meu cartão OpenGPG. Batching não é trivial, mas o programa python Eu usei eu fiz disponível em bitbucket
Anthon
Eu gosto das duas respostas e os dois sugerem a solução certa. obrigado pelo link bitbucket!
humanityANDpeace
1
Gerando um novo processo consome entropia, portanto, uma abordagem melhor seria usar o readbuiltin shell:while read -r < /proc/sys/kernel/random/entropy_avail; do clear; date; printf '\nAvailable entropy: %s bytes\n' "$REPLY"; sleep 1; done
nyuszika7h