Segurança

Um modelo de confiança que é explicado pode ser auditado; um que é escondido, não. Isto é o que o SecureChat faz, e também o que ele não faz.

Em resumo

Como uma mensagem é criptografada (envelope v1)

Usamos a libsodium, uma biblioteca criptográfica auditada e amplamente utilizada. Estas são as peças do envelope v1 (sc1):

Primitivas criptográficas do envelope v1
PeçaConstrução
Identidade (o seu aparelho e a empresa)Par de chaves X25519
Chave da conversa32 bytes aleatórios gerados pelo seu celular ao resgatar o convite. Se nós a gerássemos, nós a conheceríamos.
Distribuição dessa chaveEla é selada separadamente (crypto_box_seal) para a sua chave pública e para a da empresa. Nós só guardamos os dois envelopes selados.
Criptografia de cada mensagemXChaCha20-Poly1305 com nonce aleatório de 24 bytes
Dados associadosCada mensagem fica vinculada à sua conversa, a quem a envia, ao seu identificador e à versão da chave. Um servidor não pode movê-la para outra conversa, duplicá-la com outro identificador nem fazer uma mensagem sua passar por uma da empresa.
PreenchimentoAté múltiplos de 256 bytes, para ocultar o tamanho exato
Assinatura da chave da empresaEd25519, com a chave da plataforma
Assinatura da rotação de chaveEd25519, com a chave de assinatura da própria empresa (mais abaixo)
Impressões digitaisBLAKE2b-256 com separação de domínio

Anexos criptografados

Fotos e documentos são criptografados no aparelho que os envia (o seu celular ou o servidor da empresa), assim como o texto:

O que protege

O que não protege

Chave da plataforma e verificação de empresas

Antes que uma empresa possa enviar convites, verificamos a sua existência legal, se ela controla o seu domínio (registro DNS) e o número de WhatsApp de onde convida. Depois, assinamos a chave pública dela com a nossa chave de plataforma Ed25519. O app verifica essa assinatura e mostra o selo de Empresa verificada.

Chave pública da plataforma (Ed25519, base64url):

qxh_sOak_wQVqZifJjDcoy-TeWIF3NADjqsjta0GPlw

O que é assinado é exatamente SecureChat|v1|company-key|<companyId>|<keyVersion>|<chave pública>. Isso concentra o risco em nós: se alguém roubasse a chave da plataforma, poderia se passar por uma marca. Por isso também existe a verificação do link.

A empresa gera o seu próprio par de chaves na sua infraestrutura com o nosso SDK (npx @securechat/sdk keygen) e só envia a chave pública para nós. O portal não oferece a opção de gerá-la no navegador: se a chave privada passasse pelos nossos servidores, a promessa deixaria de ser verificável.

Empresas não verificadas e Modo de testes

Para que uma empresa possa testar a sua integração enquanto a analisamos, ela pode criar convites de teste. A chave dela não está assinada como verificada, então qualquer pessoa poderia se cadastrar como “Banco X” e usá-los para se passar por uma marca. Por isso:

A criptografia é a mesma de uma conversa normal. O que muda é a garantia de identidade: em uma conversa de teste, não verificamos quem é a empresa.

A impressão digital no link de convite

Quando a empresa cria o convite com o SDK, ela acrescenta ao link um fragmento #s=…&fp=…. O navegador não envia o fragmento ao servidor, então nós não o vemos, mas o link viaja pelo WhatsApp, um canal que não controlamos. Ao resgatar o convite:

  1. O app verifica se a chave da empresa que fornecemos tem a impressão digital fp do link.
  2. O app vincula a sua própria chave ao segredo s com um MAC, e a empresa o verifica.

Se substituíssemos qualquer uma das duas chaves, uma das duas pontas perceberia. Limites: só cobre o resgate por link, não o código curto digitado, e os convites criados manualmente no portal não levam esse segredo.

Rotação de chave assinada pela empresa

Além da chave de criptografia, a empresa gera com o SDK uma chave de assinatura Ed25519 que também fica na infraestrutura dela; só a chave pública é enviada para nós. O app a fixa no primeiro contato, junto com a de criptografia. Quando a empresa faz a rotação da chave de criptografia, ela assina a mudança com essa chave de assinatura: SecureChat|v1|company-key-rotation|<companyId>|<versão anterior>|<chave anterior>|<versão nova>|<chave nova>. Verificamos a assinatura antes de aceitar a chave nova, e o app a verifica de novo.

Por que isso importa: só com a nossa assinatura de plataforma, uma rotação legítima e uma falsificação feita por nós pareceriam iguais. Com a assinatura da empresa, se passar por uma empresa que você já tem fixada exige a chave de assinatura dela, que nunca passa por nós. A assinatura da plataforma continua obrigatória nos dois casos. Por enquanto, a chave de assinatura não é rotacionada: trocá-la é tratado como uma rotação sem assinatura.

Sem forward secrecy na v1

Cada conversa usa uma chave estável. Se no futuro a sua chave privada ou a da empresa vazasse, junto com as mensagens criptografadas armazenadas, as mensagens anteriores dessa conversa também poderiam ser descriptografadas. Protocolos como o Signal renovam as chaves a cada mensagem para evitar isso; deixamos esse recurso de fora da primeira versão do protocolo de forma deliberada, e ele está no nosso roadmap.

Metadados

Mesmo sem ver o conteúdo, vemos quem fala com qual empresa, quando e com que frequência, o tamanho aproximado de cada mensagem (arredondado para 256 bytes), o tamanho e a data de cada anexo, endereços IP e dados do aparelho. Isso basta para inferir bastante coisa, e por isso declaramos tudo na política de privacidade.

O histórico fica vinculado ao seu aparelho: se você o perder, recupera cada conversa com um novo convite da empresa, que sela a chave novamente para o seu novo aparelho.

Reportar uma vulnerabilidade

Escreva para soporte@securechat-app.com com o assunto “Segurança”. Pedimos um prazo razoável para corrigi-la antes de torná-la pública.