Bitmask
Comunicação encriptada para meros mortais 
 (super-herois também são bem-vindos)

Detalhes da Criptografia do Bitmask

Você pediu por detalhes de criptografia, aqui estão. Tentaremos documentar toda a criptografia usada pelo Bitmask, e um pouco dos pensamentos por trás dessas decisões. Para mais detalhes, dê uma olhada no código-fonte ou navegue pela nossa documentação técnica.

Autenticação – Senha Remota Segura

Bitmask usa Senha Remota Segura (SRS) para autenticar com o provedor de serviço. SRS é um tipo de prova de conhecimento-zero para autenticação via nome de usuário e senha que não fornece ao servidor uma cópia da própria senha. Tipicamente, os sistemas de senhas funcionam mandando uma cópia purotexto da senha para o servidor, que em seguida embaralha essa senha e salva-a. Com a SRS, o cliente e o servidor negociam um “verificador de senha” após várias round trips. O servidor nunca tem acesso ao purotexto da senha.

Um benefício adicional da SRS é que ambas partes autenticam uma à outra. Com as senhas embaralhadas tradicionais, o servidor pode dizer que a senha estava certa mesmo se não tivesse ideia de qual era a senha real. Com a SRS, o usuário autentica com o servidor e o servidor também autentica com o usuário.

Atualmente usamos parâmetros de logaritmo discreto de 1024-bit. Estamos vendo de aumentá-los para 2048-bit.

Existem algumas limitações com a SRS. Um servidor comprometido ou duvidoso pode tentar quebrar uma senha por força bruta tentando milhões de combinações, da mesma forma que com senhas embaralhadas comuns. Por isso, ainda assim é importante escolher uma senha forte. Na prática, entretanto, os usuários são terríveis para escolher senhas fortes.

Uma segunda limitação tem a ver com a aplicação web. Ela também usa SRS, mas o códido SRS em javascript é carregado do provedor. Se o provedor está comprometido ou é duvidoso, ele pode carregar algum outro javascript para capturar a senha do usuário.

Temos três planos para futuramente superar esses problemas potenciais:

  1. Permitir o uso de uma chave longa e aleatória adicional que seja requerida como parte do processo de autenticação (opcionalmente). Por exemplo, cada dispositivo que um usuário tenha o Bitmask instalado poderia ter uma “chave de dispositivo” e o usuário precisaria autorizar essas chaves de dispositivo antes que ele rodasse o Bitmask em um novo dispositivo.
  2. Também planejamos incluir com o Bitmask um filtro de bloom das 10.000 senhas mais comumente usadas. Segundo algumas pesquisas, 98,8% de todos os usuários escolhem uma senha entre essas 10.000. Um filtro de bloom é relativamente pequeno e podemos simplesmente proibir que o usuário selecione qualquer uma dessas senhas (embora com alguns falso positivos).
  3. Permitir que os provedores proibam autenticação via aplicação web. A autenticação deveria acontecer pelo aplicativo do Bitmask que, em seguida, carregaria o website com um token de seção obtido. Desta forma, o código crítico de autenticação da SRS nunca é carregado do provedor.

Para mais informações, ver:

Transporte – TLS

O cliente Bitmask frequentemente realiza várias conexões com o provedor usando TLS. Por exemplo, para verificar se existe uma atualização da lista de gateways de VPN.

Quando um provedor de serviço é adicionado pelo BItmask, o certificado CA é baixado do provedor por uma conexão TLS comum autenticada usando o sistema x.509 CA existente. Este é o único momento em que o Bitmask depende do sistema de CA.

Todas as conexões subsequentes com aquele provedor usam o CA específico do provedor para autenticar a conexão TLS. Essencialmente, esta é uma forma de pinning certificate e TOFU. Para que um atacante personifique um provedor, será preciso apresentar um certificado x.509 falso de servidor autenticado por uma Autoridade Certificadora, e assim interceptar e reescrever todo o tráfego subsequente entre o cliente Bitmask e o provedor.

Se um provedor já foi sido semeado previamente (pre-seeded) com uma aplicação Bitmask, então a impressão digital do certificado CA específico do provedor já é conhecida de antemão. Nesses casos, o sistema CA x.509 nunca é invocado.

Os certificados CA específicos de provedores usam RSA de 4096 bit com digest de SHA256, por padrão. Os certificados do servidor usamRSA de 4096 bit com digest de SHA256, por padrão. Estes padrões podem ser alterados facilmente.

Todas as conexões TLS usan cifras PFS.

Armazenamento – Soledad

A aplicação Bitmask armazena seus próprios dados na Soledad, que lida com a encriptação desses dados, fazendo backups seguros, e sincroniza-os entre os dispositivos do usuário. Na Soledad, o armazenamento local utiliza bloco simétrico de encriptação de toda a base de dados usando uma única chave. Para os dados armazenados remotamente, cada documento é encriptado separadamente usando uma chave única para cada um deles.

Tanto as chaves do armazenamento local quanto as do remoto derivam de um “segredo de armazenamento” mestre. Este segredo longo e aleatório é armazenado localmente no disco, protegido por encriptação simétrica usando uma chave derivada da senha de usuário (scrypt é usado como função de derivação da chave).

Atualmente, nossos parâmetros para o scrypt são:

N (CPU/parâmetro de custo de memória) = 2^14 = 16384
p (parâmetro de paralelização) = 1
r (tamanho do bloco misturado pelo SMix()) = 8
dkLen (tamanho da chave derivada) = 32 bytes = 256 bits

Estamos vendo de usar um N maior.

Armazenamento local

A base de dados SQLite local encriptada em bloco usa AES-256-CBC usando os primeiros 256 bits do segredo de armazenamento. Ver github.com/kalikaneko/python-u1dbcipher and sqlcipher.net.

Armazenamento remoto

A encriptação de cada documento no armazenamento remoto usa encriptação simétrica com AES-256-CTR ou cifra XSalsa20 usando chaves de 256 bit. Usamos a biblioteca pycryptopp para isso. A chave e o MAC usados para encriptar cada documento individualmente são derivados da seguinte forma:

storage_secret_a = primeiros 256 bits do segredo de armazenamento
storage_secret_b = tudo que venha depois dos primeiros 256 bits do segredo de armazenamento
document_key = hmac(document_id, storage_secret_b)
document_mac = hmac(document_id | document_revision | iv | ciphertext, hmac(document_id, storage_secret_a)

Cada documento possui sua própria chave. A revisão do documento no MAC do documento previne a sobreposição de uma antiga versão sobre uma nova. HMAC usa SHA256.

Alguns documentos nos dados remotos de usuário são adicionados pelo provedor, tais como no caso de novos emails. Estes documentos usam encriptação assimétrica, sendo cada documento encriptado usando a chave pública OpenPGP do usuário. Usamos a biblioteca derivada do python-gnupg Isis para isso. Esses documentos são armazenados apenas temporariamente dessa forma: assim que o cliente os tiver visto, eles são desencriptados e re-encriptados usando os outros métodos.

Transporte

TLS, como acima. Em breve será com CurveZMQ.

Tunel Encriptado – OpenVPN

OpenVPN possui três configurações que controlam quais cifras são usadas (existe uma quarta, --tls-auth, mas ainda não podemos usá-la num ambiente público de múltiplos usuários). Cada provedor pode facilmente escolher a opção que quiser. Abaixo estão os padrões atuais que vêm com a plataforma LEAP.

tls-cipher

A opção --tls-cipher governa o processo de autenticação de seção da OpenVPN. Se ela é comprimetida, você pode estar se comunicando com um atacante MiTM. A parte TLS da OpenVPN autentica o servidor e o cliente entre si, e negocia o material aleatório usado no resumo [digest] do pacote de autenticação e a encriptação de pacotes.

Ao invés de permitir muitas opções, o Bitmask suporta uma única cifra apenas (para prevenir ataques de reversão [rollback attacks]).

Por enquanto, escolhemos o DHE-RSA-AES128-SHA. O mais importante é escolher uma cifra que suporte PFS, como todas as cifras DHE fazem.

Escolhemos AES-128 porque existem ponto fracos conhecidos com os padrões de chaves AES-192 e AES-256 [key schedules]. Não existe nenhuma fraqueza conhecida com relação a ataques de força bruta contra 14 ciclos na AES-256, mas saber de fraquezas da AES-256 usando outros valores de ciclos é, em geral, suficiente para recomendar AES-128 ao invés da AES-256. Para mais informações, ver a postagem de Bruce Scheier Another New AES Attack.

Preferiríamos usar ECC no lugar da RSA, e planejamos em fazer isso em algum momento. ECC é um pouco mais complicado e involve mudanças no nosso código TLS em diversos lugares (tendo que recompilar a openvpn, e alterar as bibliotecas de geração de certificados usadas pelos sysadmins e pelo API do provedor).

O padrão autal dos certificados x.509 do cliente e do servidor usados pelo OpenVPN é o 2048 bit RSA e o 4096 bit RSA (respectivamente) com digest de SHA256. Tudo isso também é facilmente configurável pelo provedor (para ver todas as opções, rode o leap inspect provider.json).

auth

A opção --auth determina qual hashing digest é usado para autenticar cada pacote do tráfego usando HMAC.

Escolhemos manter o SHA1 como digest padrão ao invés de usar o SHA256. Se um atacante consegue quebrar um SHA1 HMAC em cada pacote em tempo real, você tem problemas muito maiores que a sua VPN.

cipher

A opção --cipher determina como os próprios pacotes do tráfego são encriptados. Escolhemos o AES-128-CBC.

Na verdade, o padrão da OpenVPN provavelmente é melhor que AES-128, desde que passou a usar Blowfish. Escolhemos o AES-128 porque a cifra TLS já depende do AES-128. Normalmente preferiríamos o modo de cifra OFB ao invés do CBC, mas o manual da OpenVPN diz que o “CBC é recomendado e o CFB e o OFB devem ser considerados para modos avançados”.

obfsproxy

O Obfsproxy é usado opcionalmente para fazer com que o tráfego VPN não se pareça com um tráfego VPN para alguém que estiver monitorando a rede. Obfsproxy usa módulos chamados ‘pluggable transports’ para ofuscar o tráfego oculto. Transportes diferentes podem ou não ser encriptados e possuem implementeções e escolhas de esquemas de encriptação diferentes.

Escolhemos o ‘pluggable transport’ Scramblesuit, que usa Uniform Diffie-Hellman para o handshake inicial e AES-CTR 256 para os dados da aplicação.

Email encriptado – OpenPGP

O par de chaves de usuário auto-gerados usam RSA de 4096 bit para a chave de assinatura mestra [master signing key].

O Bitmask não encriptará a chave pública de um destinatário se o seu comprimento for igual ou inferior a 1024 bit.

Todas as chaves estão armazenadas na Soledad.

O Bitmask ainda não suporta chaves ECC.

O Bitmask usa GnuPG. A biblioteca em python que usamos é a ramificação Isis do python-gnupg.

Atualizações de Segurança – TUF

As atualizações de segurança são feitas usando o TUF, que usa chaves RSA OpenSSL 4096 com pyCrypto. Existe três chaves envolvidas no processo de atualização (root, targets e timestamp).

  • A chave ‘root’ é usada para certificar o resto das chaves que estão armazenadas offline e é usada somente uma vez por ano para atualizar a certificação ou no caso de mudança de alguma outra chave [key rotation].
  • A chave ‘targets’ é usada para assinar todas as atualizações. Esta chave está nas mãos do gerenciador de lançamentos [release] e é usada a cada nova versão.
  • A chave ‘timestamp’ é usada para assinar um arquivo com data e hora a cada dia. Este arquivo é usada pelo cliente para prevenir que um adversário imponha uma atualização antiga. Esta chave está online nos servidores da plataforma.

Outros

OpenSSH

Por padrão, todos os servidores usam chave RSA para guardar as chaves ao invés de ECDSA. Se um ‘host’ possui uma chave ECDSA, a plataforma irá sugerir ao ‘sysadmin’ que mude para RSA. No futuro, quando o Curve255219 for bem suportado, a plataforma instigará a mudar para 25519.

DNSSec

Ainda será escrito.

StartTLS + DANE

Ainda será escrito.