Marllus
Marllus Cientista da computação, doutorando em educação, mestre em políticas públicas, professor, poeta, escritor, artista digital e aspirante a tudo que lhe der na telha.

Utilizando criptografia PGP em um formulário HTML

Utilizando criptografia PGP em um formulário HTML
Photo by Mauro Sbicego

Criptografia sempre é um termo interessante, e quando se tem a possibilidade de a inserir nas mais diversas aplicações e processos pessoais ou profissionais, é uma vantagem. Neste tutorial, ensinarei como criar um formulário de contato com criptografia PGP, somente com html e javascript. Isso quer dizer que você não precisará instalar nada em back-end (servidor onde hospeda o site). Esse procedimento cai como uma luva em sites estáticos, ou criados por Geradores de Sites Estáticos (SSG), como Jekyll.

O que é PGP?

PGP significa Pretty Good Privacy (ou Privacidade muito boa), e é um tipo de criptografia assimétrica, também chamada de criptografia de chave pública. Foi criada por Phil Zimmerman em 1991. Apesar de ter atualmente quase 30 anos de existência, ela ainda continua sendo uma das principais métodos criptográficos da atualidade, e que serve como base para o funcionamento de várias aplicações existentes.

Mas por que ela é tão boa?

Simples, quando você cria um par de chaves (chave pública e privada), você distribui essa chave pública para todos. Quando alguém quer enviar uma mensagem criptografada para você, basta ela criptografar esse texto ou arquivo usando a sua chave pública. Então, quando receber essa mensagem somente você, como detentor da chave privada em questão, conseguirá abrir. O que estou falando, basicamente, é que somente o detentor de uma chave privada conseguirá descriptografar uma mensagem que foi originalmente criptografada com a chave pública referente. Cada usuário que gera um par de chaves, gera uma chave privada e uma outra pública. São como irmãs em vida, uma precisa da outra pra sobreviver.

Bem, existem vários métodos de se trabalhar com PGP, mas aqui o foco será tag html, especificamente a <textarea>.

Os passos necessários para criação de chave PGP e inserção em servidores públicos de chave pública serão mostrados em tutoriais futuros. Aguardem.

Inserindo PGP no formulário do seu site

Bem, a ideia é utilizar sua chave pública no seu site, então colocar por trás de um javascript e fazer com que ele seja chamado com o clique de um botão, usando somente html. Então tudo que o usuário tiver escrito dentro da caixa de texto irá ser criptografado.

Há algumas implementações de PGP em javascript, como a da Keybase e a do Protonmail. Aqui, iremos utilizar essa última, a OpenPGP.js.

Implementação

Primeiro, você precisará do arquivo da biblioteca OpenPGP, o openpgp.min.js. Você pode tanto baixá-lo, quanto chamá-lo via CDN, chamando o link dentro do html.

Agora, você precisa de um arquivo javascript que irá conter sua chave pública. Vamos chamá-lo de crypto.min.js. Então, crie este arquivo, copie e cole o conteúdo abaixo dentro dele e o substitua com sua chave pública, após o “BEGIN PGP PUBLIC KEY BLOCK”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
`jQuery(document).ready(function(){$("#button").one("click",function(){if(!window.crypto.getRandomValues)return $("#button").val("Error"),window.alert("This browser isn't supported!"),!1;if("Encrypt"===$("#button").html()){var pubkey="-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"\n" +
"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\n" +
"yUQ+e6aB+0k=\n" +
"=zSWN\n" +
"-----END PGP PUBLIC KEY BLOCK-----";t=openpgp.key.readArmored(pubkey),n=openpgp.encryptMessage(t.keys,$("#input").val());return $("#input").val(n),$("#button").html("Done!"),!0}$("#input").val(""),$("#button").html("Encrypt")})});` 

No exemplo acima, eu utilizei minha chave pública. Somente substitua a chave acima pela sua.

Agora, na página html em questão, adicione o conteúdo abaixo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<textarea id="input" class="contact-form" style="width: 300px; height: 140px;"></textarea><br>
<button id="button" class="btn btn-warning">Encrypt</button> 
<button id="button" class="btn btn-warning" onclick="copy()">Copy</button>

<script>
    function copy() {
    let textarea = document.getElementById("input");
    textarea.select();
    document.execCommand("copy");
}
</script>

<script src="./js/jquery.min.js"></script>
<script src="./js/openpgp.min.js"></script>
<script src="./js/crypto.min.js"></script>

Esse código acima adiciona a área de texto, dois botões (criptografar e copiar o código). Logo abaixo, está um função javascript que o copiará o texto digitado que foi criptografado ao clicar no botão encrypt. Atente-se para alterar o local onde estão os scripts e faça a alteração, nas três últimas linhas.

Pronto. Seu formulário usando PGP já está pronto. O usuário pode criptografar, copiar a mensagem e lhe enviar por qualquer meio (até inseguro). Como a criptografia será fim a fim, estará a salvo de muitos espiões desnecessários.

Você pode conferir essa implementação aqui no meu blog. Na página de contato.

Um agradecimento ao artigo do Scott Helme, que me ajudou na implementação dos arquivos javascript.

Qualquer dúvida deixe um comentário (pode ser criptografado! rs).

:)

Rating: