O programa pass é um utilitário de linha de comando para armazenar senhas e dados extras de formato livre em pequenos arquivos criptografados com gpg. Ele fornece um subcomando grep em particular para encontrar senhas por meio de dados extras.
Mas esse subcomando grep é dolorosamente lento na minha máquina. Tenho quase 200 senhas armazenadas e internamente cada arquivo é descriptografado gpg
assim (sem a time
frente, é claro):
% time gpg -d --quiet --yes --compress-algo=none --no-encrypt-to stackoverflow.gpg
the password output
user=0,000 sys=0,006 wall=0,382 (1,61)
O tempo de parede é de quase 0,4 segundos, o que equivale a cerca de 1 minuto para percorrer todos os arquivos.
O gpg-agent
está rodando e eu tenho esta versão:
gpg (GnuPG) 2.2.27
Duas suspeitas de por que isso é lento:
- A inicialização
gpg
e a comunicaçãogpg-agent
são lentas, apoiadas pelo fato de que os tempos de usuário + sistema são pequenos em comparação. gpg-agent
é lento, apoiado pelo fato de que após umapass grep
execução seu tempo cumulativo de CPU aumenta em 60 segundos, correspondendo perfeitamente ao tempo total da execução completa.
Juntos, ambos apontam para gpg-agent
, embora eu não tenha ideia de por que o agente deveria ser tão lento. Com ps
eu vejo isso funcionando como
/bin/gpg-agent --sh --daemon
Alguém pode esclarecer se ~ 0,3 segundos de CPU é razoável para o agente por arquivo ou se há uma maneira de melhorar isso?
EDITAR: Outras descobertas
Anexando strace
ao agente, encontro isto:
20200 14:57:03.701648 getrusage(RUSAGE_SELF, {ru_utime={tv_sec=133, tv_usec=890780}, ru_stime={tv_sec=0, tv_usec=99975}, ...}) = 0
20200 14:57:03.701666 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, {tv_sec=133, tv_nsec=990762100}) = 0
20200 14:57:04.063523 getpid() = 18035
onde temos 360ms entre clock_gettime
a getpid
chamada.
E com ltrace:
20472 15:04:55.035574 strlen("my-password-here") = 10
20472 15:04:55.035641 gcry_kdf_derive(0x7d884b82c008, 10, 19, 2) = 0
20472 15:04:55.394727 gcry_cipher_setkey(0x7d884b82cbc0, 0x7d884b82c030, 16, 0x7d884b83c000) = 0
Então gcry_kdf_derive
leva 360ms. Faça o que fizer, posso armazenar em cache o resultado por alguns segundos com alguma configuração. (... vai buscar o código fonte).