Perguntas sobre a geração de chaves RSA com GnuPG

Perguntas sobre a geração de chaves RSA com GnuPG

Atualmente estou fazendo um projeto de ensino médio estudando chaves RSA para melhor compreendê-las teórica e praticamente. Uma parte do projeto consiste em um experimento, e opto por testar e ver quão grande será a carga de trabalho da CPU ao gerar chaves RSA de comprimentos diferentes. Também gostaria de economizar tempo como ponto de dados, se precisar chegar a uma conclusão.

A máquina está executando o Ubuntu 16.04 e os aplicativos são baixados dos repositórios padrão.

O plano é usar GnuPG para gerar chaves RSA de diferentes comprimentos (1024, 2048 e 4096) e GNU Time para obter a carga de trabalho da CPU e o tempo de execução do processo. O processo será automatizado com um script python e será mais ou menos assim:

  1. Para comprimento em [1024, 2048, 4096]:

    1.1. Por X vezes:

    1.1.1. Execute o comando Gnu PG e monitore os recursos do sistema

    1.1.2. Gravar o uso de recursos do sistema em arquivo

Depois traçarei alguns gráficos para ver se minha hipótese está correta.

Mas recebi algumas dúvidas sobre a implementação do meu teste GnuPG. Uma explicação de como minha implementação virá após as perguntas. Minhas perguntas são:

  • Essas configurações fazem o que eu quero fazer?
  • Posso de alguma forma desativar a criação automática de certificados revogados?
  • Por que demora muito mais para gerar algumas chaves?
  • Por que o GnuPG responde que foram necessários 0 segundos de CPU no espaço do usuário para a criação das chaves? Isso é feito em outro processo?
  • Por que o parâmetro de carga de trabalho da CPU só mostra um valor (0 < CPU) quando demorou menos de um segundo (relógio de parede > 1) para criar as chaves?

Lendo o manual parece que a forma mais simples de gerar as chaves é com a --batchopção ativada. Eu configurei as opções em um arquivo com as seguintes instruções:

# Text syntax in this file
#%dry-run

%echo Generating RSA key...

# Don't ask after passphrase
%no-protection

Key-type: RSA
Key-Length: 1024
Name-Real: Real Name
Name-Email: [email protected]
Expire-Date: 0

# Generate RSA key
%commit

%echo Done!

O comando que executa este arquivo possui duas partes, a parte Gnu Time e a parte GnuPG. O comando GNU Time tem a seguinte aparência:

$ time --format="Wall clock: %e[s], CPU (userspace): %U[s], CPU (workload): %P%"

E o comando do GnuPG é o seguinte.

$ gpg2 --gen-key --homedir=./rsa-keys --batch [filename]

O comando que executo no meu shell (fish shell se for importante) é o seguinte (GNU Time + GnuPG):

$ time --format="Wall clock: %e[s], CPU (userspace): %U[s], CPU (workload): %P%" gpg2 --gen-key --homedir=./rsa-keys --batch [filename]

Saída do comando:

Wall clock: 36.83[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 0.04[s], CPU (userspace): 0.00[s], CPU (workload): 8%
Wall clock: 4.76[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 72.39[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 57.52[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 84.71[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 63.32[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 51.10[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 47.58[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 64.72[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 0.05[s], CPU (userspace): 0.00[s], CPU (workload): 6%
Wall clock: 0.03[s], CPU (userspace): 0.00[s], CPU (workload): 11%
Wall clock: 29.62[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 55.02[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 36.08[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 42.92[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 40.41[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 204.36[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 246.42[s], CPU (userspace): 0.00[s], CPU (workload): 0%
Wall clock: 51.50[s], CPU (userspace): 0.00[s], CPU (workload): 0%

Responder1

GnuPG lê from /dev/random, que bloqueia quando não há entropia suficiente disponível (que é um comportamento discutível). O esforço computacional real é bastante insignificante. Você também pode observar que a primeira/poucas execuções terminam mais rapidamente, pois o pool de entropia ainda estava preenchido com "bits novos". Eu recomendo executar watch cat /proc/sys/kernel/random/entropy_availem um terminal adicional para entender quando o GnuPG é executado em modo de "baixa entropia".

Nas plataformas de hardware atuais, os processos bloqueados por IO ou em suspensão serão colocados em segundo plano, portanto, nenhum tempo de CPU será contabilizado.

$ time --format='Wall clock: %e[s], CPU (userspace): %U[s], CPU (workload): %P%' sleep 5
Wall clock: 5.00[s], CPU (userspace): 0.00[s], CPU (workload): 0%

Isto também é visível ao copiar alguns bytes /dev/random(o que pode levar algum tempo, especialmente em máquinas virtuais):

time --format='Wall clock: %e[s], CPU (userspace): %U[s], CPU (workload): %P%' dd if=/dev/random of=/dev/null bs=1 count=512
512+0 records in
512+0 records out
512 bytes copied, 210.672 s, 0.0 kB/s
Wall clock: 210.67[s], CPU (userspace): 0.00[s], CPU (workload): 0%

Finalmente, isso também explica por que as iterações rápidas tiveram uma carga de trabalho de CPU muito maior: como os processos foram bloqueados na espera de IO por um período de tempo muito menor, a parcela do tempo de computação real do tempo de execução total é muito maior.

informação relacionada