Saltar para a documentação
Base de conhecimento

Encriptação ponta a ponta

Chaves OpenPGP criadas no seu browser. O correio que envia para outro endereço OpenEmail pode ser selado antes de sair do separador, e o correio selado endereçado a si abre no painel de leitura, desencriptado na sua máquina. As chaves nunca são nossas para entregar.

Detalhes

  • As duas metades estão ligadas de ponta a ponta. Escrever para um destinatário cuja chave está publicada sela o corpo no browser antes de o pedido sair; o servidor recebe uma armadura que não consegue ler, marca-a como pgp-mime, e constrói uma verdadeira mensagem multipart/encrypted. A leitura corre da mesma forma ao contrário: o texto cifrado é obtido, desencriptado no separador e apresentado como correio normal.
  • O algoritmo é o que toda a gente já usa: OpenPGP, através do openpgp.js, e PGP/MIME na ligação. Uma chave v4 em Curve25519, a mesma forma que a Proton emite e que o gpg produz com o seu algoritmo moderno por omissão. Assim, o correio que isto lê é em princípio o mesmo correio que o Thunderbird, o gpg e a Proton produzem, e nada aqui é um formato nosso que teria de ser desfeito mais tarde.
  • Na prática, porém, é de OpenEmail para OpenEmail. Não existe Web Key Directory, nem consulta a keyserver, nem interpretação de cabeçalhos Autocrypt em lado nenhum deste código: o único sítio onde a chave de um destinatário é alguma vez encontrada é o nosso próprio diretório, que guarda chaves publicadas a partir desta aplicação por pessoas cujo endereço está num domínio alojado aqui. Também não há forma de distribuir a sua chave. A aplicação publica a sua metade pública nesse diretório e não oferece cópia nem exportação dela, por isso um correspondente no Thunderbird não tem forma suportada de a obter. Interoperar com o mundo PGP mais alargado é uma propriedade do formato, não algo que o produto ainda faça por si.
  • A leitura não está limitada assim, porque a desencriptação não precisa de um diretório. Qualquer mensagem PGP/MIME ou PGP em linha que chegue a esta caixa de correio selada para uma chave neste browser abre, quem quer que a tenha enviado e seja qual for o cliente que usou. Isso inclui mensagens seladas para uma chave de que entretanto se afastou: as chaves reformadas ficam no chaveiro e são tentadas ao lado da atual, por isso rodar não lhe custa o correio que já recebeu.
  • Verde significa aberta, e não se chega lá de nenhuma outra forma. A linha Detalhes → Segurança só fica verde depois de uma desencriptação ter realmente devolvido texto simples neste separador, nunca a partir de um campo da mensagem, nunca a partir do facto de ter chegado um envelope encriptado. Lê-se “Encriptada ponta a ponta. Aberta com a sua chave neste browser”. Tudo o que fica aquém disso tem a sua própria frase em vez de uma partilhada: ainda a procurar, chave bloqueada, selada para uma chave que este browser não tem, não foi possível abrir, nenhuma chave aqui de todo, e este browser não nos deixou verificar. “Não conseguimos verificar” e “não tem a chave” são afirmações diferentes e a linha obriga-o a ler qual delas recebeu.
  • O S/MIME continua a não poder ser aberto. É CMS sob um certificado X.509, o openpgp.js não lhe toca, e não há no produto um arquivo de certificados que guardasse a chave se conseguisse, por isso uma mensagem S/MIME diz que a OpenEmail não a consegue abrir, e não lhe é oferecido um desbloqueio que não faria nada.
  • A metade privada é gerada no seu browser e nunca sai dele: nem encriptada, nem dentro de uma cópia de segurança, nem numa ferramenta de suporte. Nunca é enviada ao servidor, por isso não há aqui nada para entregar, intimar ou vazar. É guardada bloqueada por frase-passe numa base de dados IndexedDB própria, openemail-keyring, deliberadamente fora do alcance do conselho “limpe a cache” e da reposição da consola de depuração: ambos limpam a cache de consultas, e uma chave guardada ao lado dela faria com que um conselho de suporte de rotina destruísse permanentemente todas as mensagens encriptadas que a conta alguma vez recebeu. Eliminar a sua conta elimina-a mesmo, porque aí o correio vai também. Desbloqueá-la mantém-na em memória durante 15 minutos de inatividade e 8 horas no máximo, ao fim das quais ler a mensagem selada seguinte pede de novo a frase-passe.
  • Não há custódia nem recuperação, e isso é permanente e não por construir. A sua frase-passe é a única entrada; esqueça-a e todas as mensagens que alguém lhe selou ficam nos nossos servidores como texto cifrado que ninguém consegue ler, nós incluídos. O correio está perdido, e nenhuma insistência o recupera. O ecrã de inscrição di-lo antes de a primeira chave existir, atrás de uma caixa que tem de marcar, e o ficheiro de cópia de segurança é obrigatório, e o botão Concluído fica desativado até o ter transferido. Esse ficheiro é escrito sem o reforço extra em repouso que este browser usa, de propósito, para que continue a importar em versões antigas do gpg: uma cópia de segurança que não consegue abrir noutro sítio não é uma cópia de segurança. A chave vive também num browser num dispositivo, e um telemóvel ou um segundo portátil não têm nada até importar esse ficheiro lá.
  • O diretório guarda chaves públicas e mais nada, e uma chave pertence a uma pessoa e não a uma caixa de correio, já que uma chave ligada a um endereço teria de ser copiada entre todos com quem esse endereço é partilhado, o que é custódia com outro nome. Consultar uma exige uma sessão iniciada e permissão para enviar, nunca um endpoint público, porque um sondar aberto de endereços é um oráculo que diz a qualquer um que endereços são caixas de correio ativas aqui. Responde de forma idêntica a “não alojamos isso” e “alojamos e ninguém publicou uma chave”, já que distinguir os dois apenas move o oráculo para trás de um início de sessão em vez de o remover. E uma chave deixa de ser distribuída no momento em que o dono perde o acesso ao endereço, e não quando alguém se lembra de a revogar.
  • Todos os bytes são selados no browser no momento em que os escreve, e é isso que faz os envios adiados funcionarem de todo: uma mensagem agendada ou uma que está na janela de anulação é guardada como texto cifrado e despachada mais tarde por uma fila que não tem chave nenhuma e não consegue ler nada dela. Um destinatário cuja consulta ao diretório FALHOU bloqueia o envio, em vez de ser tratado em silêncio como não tendo chave. E uma mensagem selada só sai por um caminho que transporta uma mensagem inteira. Um caminho de saída que recebesse um corpo HTML publicaria a armadura como texto visível e reportaria sucesso, por isso um envio que aterrasse ali é recusado antes de sair um byte e não depois.
  • O que selar vai custar, medido em vez de adivinhado: a armadura é cerca de 1,86 vezes os bytes originais, por isso cabem aproximadamente 2,7 MB de anexos nos 5 MB que o caminho de envio permite, e o editor recusa uma carga acima disso antes de gastar segundos a encriptar uma que o transporte rejeitaria. O correio encriptado não reporta aberturas nem cliques, porque o rastreio por destinatário funciona variando o corpo por pessoa e um bloco selado único não pode variar, e uma ligação reescrita é uma ligação que conseguimos ler, o que é o oposto da afirmação. Um envio encriptado também nunca pode ser desduplicado por uma chave de idempotência: uma chave de sessão nova torna o texto cifrado em bytes diferentes em cada tentativa, por isso uma repetição nunca tem a mesma impressão digital que o original.
  • O agendamento sela no momento da escrita, não no momento do envio. O editor constrói o texto cifrado contra as chaves que os destinatários têm no dia em que escreve, não no dia em que a mensagem sairia, a regra que este produto já aplica a modelos e traduções, onde uma mensagem agendada leva o que aprovou e não o que mudou depois. A diferença é que um modelo desatualizado está apenas fora de prazo e uma chave desatualizada é ilegível, por isso o editor nomeia a data por palavras em vez de oferecer uma ressalva: “Selada agora, enviada a …. Todos os que constam dela vão precisar da chave que têm hoje.” A recusa que protege a outra metade está implementada mas nunca disparou, porque ainda não pode existir nenhuma mensagem dessas: se existisse, editá-la depois seria recusado em vez de silenciosamente permitido, já que remendar o corpo escreveria texto simples sobre o texto cifrado e mudar os destinatários mudaria a quem foi selada, e qualquer uma das duas entrega em claro enquanto todos os ecrãs continuam a chamar-lhe encriptada.
  • Duas coisas que o editor não vai sequer oferecer, e di-lo em vez de falhar na ligação. Um modelo é renderizado no servidor a partir de uma versão publicada, por isso não há nada neste browser para selar. Uma resposta cita a conversa por baixo dela e essa citação é acrescentada depois de o corpo ser selado, deixando uma cópia legível da conversa inteira fora do selo, por isso as respostas e os reencaminhamentos não podem ser encriptados enquanto o histórico citado não for dobrado para dentro do texto cifrado.
  • Nada disto esconde a sua linha de assunto, a quem escreveu, nem quando. O assunto viaja em claro numa mensagem selada exatamente como em qualquer outra, e o painel de leitura di-lo na própria mensagem: “O assunto e os endereços viajaram em claro; este texto não.” O PGP cobre o corpo e nenhuma implementação dele cobre o resto. Os rascunhos também não são selados, porque a gravação automática continua a escrever texto simples na sua caixa de correio enquanto escreve, porque não gravar em silêncio perderia trabalho, e o cadeado divulga-o por palavras.
  • Reconhecer correio que chega selado veio primeiro e continua válido. PGP/MIME, armadura PGP em linha e S/MIME apareciam como um corpo vazio com dois anexos sem sentido, porque o parser só trata texto simples e HTML como legíveis e largava o resto na barra de ficheiros. Essas partes são agora identificadas, a estrutura do protocolo fica fora da lista de anexos, o texto cifrado é guardado intacto, que é de onde o leitor desencripta em vez de ir buscar algo novo, e uma mensagem que ninguém aqui consegue abrir continua a dizê-lo claramente.
  • Uma mensagem assinada é tratada como uma coisa à parte, porque é. O corpo de uma delas é legível, por isso a pesquisa, as regras e tudo o resto continuam a funcionar sobre ela; nunca é fechada atrás de um cadeado nem passada por uma desencriptação. A linha reporta “Assinada pelo remetente. Assinatura não verificada”, esbatida, e fica esbatida até que algo aqui consiga de facto verificar uma assinatura, o que nada faz ainda, incluindo numa mensagem que tenha sido desencriptada com sucesso. Ver que uma mensagem está selada não é o mesmo que tê-la aberto, e abri-la não é o mesmo que saber quem a selou.
  • Numa mensagem encriptada o corpo é retido de tudo o que de outro modo o leria: o excerto de pesquisa, a passagem pelo corpo do avaliador de phishing, a verificação de escrita por IA, as condições de corpo nas regras, a importação de convites de calendário e os resumos de conversa. A metade de autenticação da verificação de phishing continua a correr, porque o DMARC, o DKIM e o SPF são lidos de cabeçalhos que o texto cifrado não esconde. Desencriptar não muda nada disso. O texto simples existe apenas no separador que o abriu, por isso uma mensagem selada continua impesquisável e continua fora das funcionalidades de IA mesmo depois de a ter lido, e a tradução não é oferecida numa delas. Esse é o custo da afirmação, não uma omissão.