(GNU Privacy Guard)
O GPG (GNU Privacy Guard), também conhecido como GnuPG, é uma implementação completa e livre do padrão/suite PGP (Pretty Good Privacy) definido na RFC4880. Com ele é permitido encriptar e assinar dados e comunicações, possuindo um sistema para gerenciamento de chaves e módulos de acesso. O comando usado para isso é o "gpg", instalado por padrão na maioria das distribuições. Além disso, para quem gosta de ambiente gráfico, existem aplicações frontends para ele com interfaces bastante interativas. Algumas de suas características:
- Implementação completa do PGP;
- GPLed/Copyleft, ou seja, software livre;
- Não usa algoritmos de criptografia patentiados;
- Trabalha com o esquema de chaves pública e privada;
- Pode trabalhar com chave compartilhada/estática;
- Possui um sistema completo para gerenciamento de chaves (criar, deletar, listar, importar, exportar, verificar e editar);
- Suporta os algoritmos ElGamal, DSA, RSA, AES, 3DES, Blowfish, Twofish, CAST5, MD5, SHA-1, RIPE-MD-160 e TIGER.
- As versões mais recentes já suportam o S/MIME;
- Pode ser usado como um backend em scripts;
- e muitas outras funcionalidades;
- Só para conhecimento, esse assunto é cobrado nas provas de certificação LPI (Linux Professional Institute).
Instalação
$ apt-get update ; apt-get install gnupg (esse pacote já é instalado por padrão na maioria das distribuições. Só para constar, já existe a versão 2 do gpg e para instalar utilize o nome "gnupg2")
(chave pública e privada)
A criptografia assimétrica consiste no uso de duas chaves: uma privada e outra pública. A chave privada tem um caráter pessoal, intrasferível, protegida e somente o seu dono pode conhecer e manipular. Já a chave pública como o seu nome mesmo diz é de caráter público, onde todos podem conhecer e copiar. Outra diferença entre elas é que a chave privada tem a função de decriptar dados e/ou realizar a assinatura digital. Já a chave pública tem a função de encriptar dados e/ou verificar a assinatura digital.
O esquema de criptografia assimétrica tem como premissa duas chaves como já foi visto nos parágrafos anteriores. Contudo, é importante evidenciar que o que uma chave faz a outra defaz. Por exemplo, se um arquivo for encriptado utilizando a chave pública, somente a chave privada poderá decriptar. Se usarmos a chave pública para tentar decriptar não obteremos sucesso. A seguir são mostrados os procedimentos para a geração da chave pública e privada e também muitas outras funcionalidades:
Geração das chaves pública e privada
$ gpg --gen-key (com esse comando um par (pública e privada) de chaves é criado)

Será solicitada a escolha de um algoritmo. Escolha "DSA and Elgamal":

Digite o seu nome completo, o endereço de e-mail, um comentário (pode ser seu apelido) e uma passphrase". Depois disso, o "gpg" necessitará gerar um valor aleatória/radômica (salt) e para isso serão capturadas ações do teclado, mouse, disco etc com o intuito de conseguir uma boa entropia. Então, durante esse momento, movimente o mouse, digite algo no teclado e acesse algum programa:

Veja que na figura acima houve um problema que a entropia não foi suficiente. Isso foi proposital, pois deixei o computador parado só para ver o que iria acontecer. Caso apareça essa mensagem, basta fazer os procedimentos solicitados (mexer o mouse, teclado etc) para que essa etapa seja concluída. Veja na figura a seguir que ao se fazer isso um par de chaves vai ser criado e assinado e o seu UID (User ID) aparecerá:

Obs1: algo interessante e que será muito solicitado ao utilizar o comando "gpg" é o "user ID" (IDENTIFICADOR DA CHAVE PUBLICA ou melhor IDENTIFICADOR DO USUÁRIO DA CHAVE PÚBLICA). Esse número identifica unicamente uma chave pública e consequentemente a pessoa dona de tal chave. No mundo não existem duas chaves públicas idênticas e consequentemente não existem dois "user ID" iguais. Veja na figura anterior, exatamente na segunda linha, esse número em hexadecimal (gpg: key D0A40404 marked as ultimately trusted). Durante a manipulação do comando "gpg" por muitas vezes será necessário especificar o "user ID". Isso, porque um usuário, além da sua própria chave, poderá ter outras chaves (públicas) de outras pessoas. Então, quando quisermos usar chaves em específico, deveremos evidenciar qual "user ID" será usado, ou seja, qual chave pública será usada.
Obs2: Conforme foi dito, um usuário além da sua própria chave, poderá ter várias outras chaves (públicas) de outras pessoas. Quando isso acontece, dizemos que esse usuário tem um chaveiro de chaves públicas (public keyrings). Normalmente uma pessoa tem uma chave privada e uma chave pública. Contudo, além dessas, ele poderá ter outras chaves públicas de outras pessoas com o intuito de criptografar dados e enviar para essas pessoas. Isso será explicado em detalhes nesse artigo.
Obs3: O "user ID", conforme foi dito, é o IDENTIFICADOR DA CHAVE. Contudo, ele pode ser qualquer caractere ou conjunto de caracteres que identifica uma chave. No início desse artigo, ao criarmos as chaves pública e privada com o comando "gpg --gen-key" foram solicitadas três informações de caráter pessoal: nome completo, endereço de e-mail e um comentário. Em questões relacionadas ao "user ID", qualquer uma dessas informações, parte/pedaço dela ou o próprio NÚMERO IDENTIFICADOR DA CHAVE podem ser usados como "user ID". Exemplo, poderíamos usar como "user ID" o nome da pessoa (ex: hugo), sobrenome (ex: azevedo), e-mail (ex: [email protected]), uma parte disso (ex: yahoo, hug, azev, df, hugo_azeve, zeved, yahoo.com etc) ou o NÚMERO IDENTIFICADOR DA CHAVE (ex: D0A40404).
Veja o diretório oculto criado e seu conteúdo, dentro do "home" do usuário atual. O arquivo "~/gnupg/pubring.gpg" é a chave pública e o "~/gnupg/secring.gpg" é a chave privada:

Veja o que o comando "file" diz sobre esses arquivos criados pelo "gpg":

Lista a(s) chave(s) pública(s)
$ gpg --list-key (lista a chave pública e as informações contida nela, conforme figura a seguir)
$ gpg --list-keys (idem)
$ gpg --list-public (idem)
$ gpg --list-public-key (idem)
$ gpg --list-public-keys (idem)
$ gpg -k (idem)

Lista a chave privada
$ gpg --list-secret (lista a chave privada e as informações contida nela, conforme figura a seguir)
$ gpg --list-secret-key (idem)
$ gpg --list-secret-keys (idem)
$ gpg -K (idem)

Lista a(s) assinatura(s) da(s) chave(s) pública(s)
$ gpg --list-sigs (o mesmo que --list-keys, mas as assinaturas são listadas também, conforme figura a seguir)
$ gpg --list-sigs D0A40404 (idem, só que especifica o "número identificador da chave". Isso é importante, pois um usuário pode possuir mais de um par de chaves)

Lista a(s) figerprint(s) da(s) chave(s) pública(s)
$ gpg --fingerprint (mostra a figerprint/impressão digital da chave também conhecida como HASH)

Obs: o interessante é que o "user ID" (NÚMERO IDENTIFICADOR CHAVE PÚBLICA) é sempre igual ao final da FINGERPRINT da chave. Veja nas duas figuras anteriores essa igualdade.
Até agora foi muito interessante, muito legal, muito bacana etc. Contudo, todavia, porém, para que "diacho" serve mesmo esse tal de GPG? Qual a sua utilidade prática? Bom, ele tem diversas utilidades e algumas delas são mostradas a seguir. Além disso, para quem está pensando na certificação LPI, é importante aprender esse assunto, pois é cobrado nas provas.
Em algum momento poderá ser necessário enviar algum documento sigiloso para alguém. Uma das maneiras de se fazer isso é encriptando tal documento com a chave pública desse alguém. Quando esse alguém já estiver de posse de tal documento encriptado, bastará decriptá-lo com a chave privada dele.
Nada impede também que uma pessoa encripte um documento com a sua própria chave pública para transportá-lo ou guardá-lo seguramente e depois o decripte com a sua própria chave privada. Para fazer todas essas funções de encriptar e decriptar, a seguir tem os comandos mostrando como:
Encriptar arquivos$ gpg -e nome_arquivo (encripta um arquivo com a chave pública. Será perguntado qual o "user ID", digite algo relacionado ao "user ID" (conceito esse que foi já explicado nesse artigo) e aperte o "Enter". Por exemplo, nesse caso poderíamos usar "hugo", "azevedo", "azev", "yahoo" etc, ou seja, qualquer caracter ou conjunto de caracteres que esteja relacinado ao "user ID")
$ gpg --encrypt nome_arquivo (idem)
$ gpg -r yahoo -e nome_arquivo (idem, só que especificando um "user ID" de uma pessoa em específico. Esse é o comando mais comum, pois ao encriptar um arquivo se deve utilizar a chave pública da pessoa que deseja enviar o arquivo)
$ vi nome_arquivo.gpg (somente para verificar que o conteúdo do arquivo foi encriptado. É importante destacar que o tamanho do arquivo encriptado aumentará)
Obs: ao encriptar um arquivo, um novo será gerado com o mesmo nome, acrescentado a extensão ".gpg". Caso deseje, se pode até deletar o arquivo original, pois o conteúdo dele estará nesse novo arquivo. Contudo, antes de fazer isso, é importate realizar a decriptação a seguir para ver o que acontece.
Decriptar arquivos
$ gpg -d nome_arquivo.gpg (decripta um arquivo com a chave privada. Será perguntada qual é "PASSPHRASE". Digite-a e aperte o "Enter")
$ gpg --decrypt nome_arquivo.gpg (idem)
Obs1: ao decriptar um arquivo, não será gerado um novo ou algo do tipo, simplesmente o conteúdo decriptado será mostrado na tela.
Obs2: sempre que é utilizada a chave privada, a PASSPHRASE é solicitada, sendo uma medida de segurança muito importante. A chave privada é utilizada basicamente para decriptar ou assinar dados.
Até aqui tudo bem. Contudo, vem uma pergunta que não quer calar sobre encriptar e decriptar dados (arquivos): Como faço para encriptar se eu não tenho a chave pública da pessoa que desejo enviar o arquivo? Bom, geralmente e de uma maneira prática, as chaves públicas são armazenadas em servidores públicos que estão na Internet. Alguns exemplos desses servidores GPG são: keyserver.veridis.com, pgp.mit.edu, usa.keyserver.net, subkeys.pgp.net etc. Contudo, o oficial e que se deve ser usado preferencialmente é o keys.gnupg.net.
Existem duas maneiras de importar uma chave pública de uma pessoa que está armazenada nesses servidores. A primeira é através do comando "gpg" que utiliza a porta TCP 11371 para a transferência da chave. A segunda é manualmente acessando a página web desses servidores e seguindo os procedimentos indicados por eles. Valendo evidenciar que geralmente esses servidores fazem sincronismo entre si, ou seja, as chaves contidas em um servidor vão ser as mesmas em todos os outros. Vou mostrar agora como importar de um servidor GPG uma chave pública de um pessoa através do comando "gpg":
Importar uma chave pública de servidor GPG público$ gpg --keyserver keys.gnupg.net --recv-keys F0A50505 (ao utilizar esse comando, a chave pública que tem user ID "F0A50505" e que está no servidor "keyserver.veridis.com", será adiciona ao chaveiro de chaves do usuário atual. Utilize o comando "gpg --list-key" para ver se esta chave pública foi realmente importada. Para saber o UID que deve ser importado, entre no site web do servidor e procure pelo nome da pessoa que desejada ou entao peca que a pessoa lhe informe o user ID dela)
Importar uma chave pública de um arquivo
$ gpg --import public_key.asc (idem, só que em vez de importar a chave pública de um servidor gpg, estamos importanto diretamente de um arquivo que contém tal chave)
De uma forma prática, é interessante armazenar as chaves públicas em servidores que estão na Internet, como foi mostrado anteriormente. No entanto, nada impedirá que alguém passe a chave pública por e-mail, pendrive, compartilhamento de arquivos, scp, ftp, sftp etc.
Para fazer a exportacao da chave publica, basta usar o comando "gpg", conforme descrito a seguir:
Exportar uma chave pública para um servidor GPG público$ gpg --send-keys F0A50505 (ao utilizar esse comando, a chave pública que tem user ID "F0A50505" e que está na maquina local, será exportada para o servidor publico GPG que por padrao [e o "keys.gnupg.net". Utilize o comando "gpg --list-key" para ver o "user ID" da chave pública que deseja exportar. Para saber se a chave exportada, entre no site web do servidor e procure pelo nome da pessoa desejada ou entao pelo user ID dela)
$ gpg --keyserver keys.gnupg.net --send-keys F0A50505 (idem, so que especificando um servidor publico GPG)
Exportar uma chave pública para um arquivo
$ gpg -a|--armor --export (exporta a(s) chave(s) pública(s) que está(ão) no seu chaveiro de chaves. A opção "-a" faz com que a chave pública apareça num formato ASCII, ao invés do formato binário que pode ser visto em arquivo "~/.gnupg/pubring.gpg". A saída padrão será a monitor. Para exportar a chave para um arquivo digite um dos dois comandos a seguir)
$ gpg -a|--armor --export -o public_key.asc (idem, só que a chave será redirecionada para o arquivo "public_key.asc")
$ gpg -a|--armor --export > public_key.asc (idem)
$ gpg --export > public_key.gpg (idem, só que sem a opção "-a" faz com que a chave pública apareça num formato binário. O conteúdo do arquivo gerado "public_key.gpg" é o mesmo do "~/.gnupg/pubring.gpg")
$ gpg --export user_ID > public_key.gpg (idem, só que especifica o "user_ID", consequentemente somente uma chave pública será exportada)
$ gpg --export user_ID -o public_key.gpg (idem)
Agora sim, é só envia o arquivo "public_key.asc" ou "public_key.gpg" que é a sua chave pública gpg aos seus colegas para que possam criptografar arquivos, mensagens etc, sendo que só você poderá decriptografar. Isso porque é o único que tem a chave privada equivalente.
Tambem [e possivel procurar chaves publicas com o comando "gpg". Veja a seguir alguns exemplos:
Procurar uma chave pública em um servidor GPG público$ gpg --search-keys F0A50505 (procura a chave publica GPG no servidor "keys.gnupg.net")
$ gpg --keyserver keys.gnupg.net --search-keys F0A50505 (idem, so que especificando um servidor publico GPG)
A assinatura de um arquivo consiste na comprovação do origem. A assinatura é feita com a chave privada que só o próprio dono pode possuir. Como a chave privada é de caráter pessoal e intransferível, então, só o próprio dono poderia realizar aquela assinatura. Já a verificação da assinatura é feita com a chave pública equivalente, a qual todos podem obter.
Assinar arquivos$ gpg -s nome_arquivo (assina um arquivo com a chave privada. Será perguntado qual é a PassPhrase. Um novo arquivo com a extensão ".gpg" será criado. É importante evidenciar que o arquivo foi encriptado também. Contudo, qualquer pessoa pode decriptá-lo com o comando "gpg -d nome_arquivo". Isso poque o arquivo é criptografado com um algoritimo simétrico e usa a PASSPHASSE como se fosse uma chave compartilha)
$ gpg --sign nome_arquivo (idem)
$ gpg --clearsign nome_arquivo (idem, só que ao invés de encriptar o arquivo, a assinatura ficará em texto claro e o conteúdo também. Um novo arquivo com a extensão ".asc" será criado. Esse arquivo poderá ser aberto com qualquer editor de texto)
$ gpg -b nome_arquivo (idem, só que faz uma assinatura separada/anexa do arquivo original que terá como extensão ".sig")
$ gpg --detach-sign nome_arquivo (idem)
$ gpg -a --detach-sign nome_arquivo (idem, só que no formato ASCII e o arquivo terá a extensão ".asc")
Verificar a assinatura
$ gpg --verify nome_arquivo.gpg (verifica quem assinou o arquivo)
$ gpg --verify nome_arquivo.asc (idem)
$ gpg --verify nome_arquivo.sig (idem)
Obs1: Lembre-se que para verificar a assinatura é necessário importar a chave pública da pessoa que assinou o arquivo, conforme já mostrado nesse artigo.
Obs2: ao verificar a assinatura de alguém, várias informações são mostradas como: a data em que o dado/arquivo foi assinado, o algoritimo usado, o user ID, o nome da pessoa, o comentário, o e-mail. Todas essa informações e principalmente o "user ID" te darão a certeza da origem/autenticidade dos dados.
Desassinar arquivos
$ gpg --decrypt nome_arquivo.gpg (verifica quem assinou o arquivo e o decripta com a chave pública da pessoa assinante)
$ gpg --decrypt nome_arquivo.asc (idem)
$ gpg --decrypt nome_arquivo.sig (idem, só que não decripta, pois esse arquivo é somente a assinatura separada/anexa sem conter o conteúdo do arquivo original)
Obs1: Lembre-se que para verificar a assinatura é necessário importar a chave pública da pessoa que assinou o arquivo, conforme já mostrado nesse artigo.
Obs2: ao verificar a assinatura de alguém, várias informações são mostradas como: a data em que o dado/arquivo foi assinado, o algoritimo usado, o user ID, o nome da pessoa, o comentário, o e-mail. Todas essa informações e principalmente o "user ID" te darão a certeza da origem/autenticidade dos dados.
Encriptar e Assinar o mesmo arquivo
$ gpg -e nome_arquivo (encripta com a chave pública da pessoa que irá receber o arquivo)
$ gpg -s nome_arquivo.gpg (assina com a minha chave privada. Será solicitada a PASSPHRASE. Um novo arquivo será criado e terá o formato "nome_arquivo.gpg.gpg")
Assinar e Encritar o mesmo arquivo
$ gpg -s nome_arquivo (assina com a minha chave privada. Será solicitada a PASSPHRASE)
$ gpg -e nome_arquivo.gpg (encripta com a chave pública da pessoa que irá receber o arquivo. Um novo arquivo será criado e terá o formato "nome_arquivo.gpg.gpg")
Obs1: não existe uma ordem, tanto faz se Encriptar e Assinar ou Assinar e Encritar. A única diferença é a ordem dos procedimentos.
Obs2: os procedimentos acima (encriptar/assinar ou assinar/encriptar) poderiam ser feitos utilizando um único comando "gpg -es nome_arquivo" ou "gpg -eas nome_arquivo". Um arquivo "nome_arquivo.gpg" ou "nome_arquivo.asc" seria criado. Para decriptar e verificar a assinatura bastaria utilizar o comando "gpg -d nome_arquivo.gpg". Já o comando "gpg -d nome_arquivo.gpg" para verificar somente a assinatura não funcionaria.
Decriptar e Dessasinar o mesmo arquivo
$ gpg -d nome_arquivo.gpg.gpg > nome_arquivo.gpg (dessasina com a chave pública da pessoa que enviou o arquivo. É interessante verificar que redirecionamento não vá substituir algum arquivo já existente, se sim dê um outro nome para o "nome_arquivo.gpg")
$ gpg -d nome_arquivo.gpg (decripta com a minha chave privada. Será solicitada a PASSPHRASE)
Dessasinar e Decriptar o mesmo arquivo
$ gpg -d nome_arquivo.gpg.gpg > nome_arquivo.gpg (decripta com a minha chave privada. Será solicitada a PASSPHRASE)
$ gpg -d nome_arquivo.gpg (dessasina com a chave pública da pessoa que enviou o arquivo. É interessante verificar que redirecionamento não vá substituir algum arquivo já existente, se sim dê um outro nome para o "nome_arquivo.gpg")
Obs: Não existe uma ordem, tanto faz se Decriptar e Desassinar ou Desassinar e Decritar. A única diferença é a ordem dos procedimentos.
A intenção de se assinar uma chave pública de alguém com a nossa chave privada é o reconhecimento da pessoa e da sua chave. Veja que ao inserir uma chave pública em um servidor GPG não nos é pedido identificação alguma. Poderíamos colocar outro nome, sobrenome etc sem que seja verificada a autênticidade das informações. Da mesma forma é o recebimento de uma chave pública por e-mail. Quem nos garante a origem desse e-mail.
Para assegurar que uma pessoa é quem diz ser, só olhando pessoalmente para ela, verificando algum documento de identidade oficial do governo (o mais correto seria o passaporte, pois é internacional) e visualmente vendo se está tudo dentro dos conformes. Só assim que podemos confiar que aquela chave pública que assinaremos é realmente daquela pessoa. Valendo relembrar mais uma vez que só depois dessa verificação é que podemos assinar uma chave pública com a nossa chave privada. Quando assinamos a chave pública de alguém, estamos dizendo que confiamos completamente nessa chave e na pessoa, sendo que temos absoluta certeza que tal chave pertence aquela pessoa.
Perceba que todas as informações de uma chave podem ser duplicadas ou falsificadas, menos o "user ID" e a "FingerPrint" que são únicos. A idéia é que além da documentação pessoal (ex: RG ou passaporte), seja verificada também o "user ID" e a "FingerPrint". Se tudo estiver ok, faça os procedimentos a seguir para assinar uma chave pública de uma pessoa:
# gpg --edit-key user_ID (entra num modo interativo habilitando o usuário a gerenciar tarefas relacionadas ao gpg. O user_ID deve ser substituído por algo que identifique a chave pública que você deseja assinar. Como pode ser observado esta chave pública já deve ter sido importada para o seu chaveiro de chaves. Para essa importação, verifique nos comandos anteriores como fazê-lo)Command> sign (assina a chave pública GPG_UID)
Command> quit (ao sair será perguntado se deseja salvar as mudanças)
ou gpg --sign-key user_ID (assina a chave pública GPG_UID)
Obs: Não é escopo desse artigo, contudo para evitar a necessidade do contato pessoal e verificação de documentos gorvenamentais e pessoais de alguém para confiarmos plenamente na sua chave pública, existe hoje em dia a famosa e badalada CA (Certifier Authority). Uma CA é uma terceira entidade nesse processo que tem a função de armazenar chaves públicas. A premissa de uma CA é que todos confiam na autênticidade de suas informações. Assim, podemos confiar nas chaves armazenadas nela, sem precisar do contato pessoal que muitas vezes é indelicado ou impossível de acontecer (ex: uma pessoa que mora no Alasca). Para inserir uma chave pública numa CA reconhecida no Brasil e no mundo, existe todo um trâmite (verificação de documentos, pagamento de taxas, segurança lógica e física, autorização/reconhecimento governamental etc) para que isso ocorra. Por causa disso, é que todos podem confiar nas chaves armazenadas numa CA (Autoridade Certificadora).
# gpg --delete-key user_ID (delete uma chave pública do seu chaveiro de chaves cuja identicação é especificado no "user_ID")
# gpg --edit-key user_ID password (muda PassPhrase da chave privada. Ao executar esse comando será solicitado para digitar um nova PassPhrase)
(chave compartilhada/estática)
A criptografia simétrica consiste no uso de uma chave com a característica de ser compartilhada e estática. Compartilhada, pois todos dentro da comunicação segura usam a mesma chave. Ela é compartilhada/enviada de maneira segura, somente pessoas específicas dentro da comunicação a possui. Estática, pois ela não muda com frequência.
Apesar da inseguraça em se trabalhar com chave simétrica, o GnuPG traz um recurso de segurança bastante útil chamada de PassPhase que é uma senha inserida no momento de encriptar os dados. Ao repassar esses dados, além da pessoa precisar da chave simétrica usada para encritar, será necessário também digitar essa PassPhrase.
Obs: o GnuPG, por padrão, utiliza o algoritmo chamado CAST5 para encriptar dados no esquema de criptografia simétrica. Para evitar a transferência de uma chave simétrica com todos que você deseja se comunicar seguramente, ao encriptar dados, é utilizada a PASSPHRASE como chave simétrica. Ela, a PASSPHRASE, será como um SALT (sal em português) utilizada pelo CAST5 para criptografar os dados. Quando for decriptar, por padrão, será utilizado o mesmo algoritmo CAST5 em conjunto com a mesma PASSPHRASE que deverá ser digita para obter os dados originais.Encriptar arquivos
$ gpg -c nome_arquivo (encripta um arquivo com a chave simétrica --> passphrase. Será solicitada a inserção de uma "PassPhrase". Um novo arquivo será criado coma a extensão "gpg")
$ gpg --symmetric nome_arquivo (idem)
Decriptar arquivos
$ gpg -d nome_arquivo.gpg (decripta um arquivo com a chave simétrica --> passphrase. Será perguntada qual é "PASSPHRASE". Digite a mesma "PASSPHRASE digitada anteriormente e aperte o "Enter")
$ gpg --decrypt nome_arquivo.gpg (idem)
Referências Bibliográgicas