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
- As mensagens são criptografadas de ponta a ponta entre o seu celular e o servidor da empresa. Nós apenas transportamos texto criptografado.
- Nunca geramos nem vemos as chaves privadas: a sua é gerada no seu celular; a da empresa, na infraestrutura dela.
- Verificamos as empresas e assinamos a chave pública delas; o app avisa você se essa chave mudar.
- A criptografia termina no backend da empresa: o que ela faz com o texto descriptografado está fora do nosso controle.
- A versão atual do protocolo não oferece forward secrecy.
- Somos o diretório de chaves dos dois lados: sem a proteção extra do link, um operador malicioso ativo (nós) poderia substituir uma chave no primeiro contato.
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):
| Peça | Construção |
|---|---|
| Identidade (o seu aparelho e a empresa) | Par de chaves X25519 |
| Chave da conversa | 32 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 chave | Ela é 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 mensagem | XChaCha20-Poly1305 com nonce aleatório de 24 bytes |
| Dados associados | Cada 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. |
| Preenchimento | Até múltiplos de 256 bytes, para ocultar o tamanho exato |
| Assinatura da chave da empresa | Ed25519, com a chave da plataforma |
| Assinatura da rotação de chave | Ed25519, com a chave de assinatura da própria empresa (mais abaixo) |
| Impressões digitais | BLAKE2b-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:
- Cada arquivo tem a sua própria chave de 32 bytes, aleatória e diferente da chave da conversa.
- Ele é criptografado em blocos de 64 KiB com XChaCha20-Poly1305. Cada bloco é autenticado junto com o identificador do anexo, a sua posição e se é o último: reordenar, cortar ou acrescentar blocos faz a descriptografia falhar.
- A chave do arquivo, o nome, o tipo, o tamanho e a impressão digital (BLAKE2b) viajam dentro de uma mensagem criptografada comum. No final, o app confere a impressão digital; se algo não bater, mostra “Não foi possível descriptografar este anexo” e nunca um arquivo pela metade.
- Nós só guardamos bytes opacos e um identificador. Vemos o tamanho do arquivo criptografado, que é praticamente o do original: os anexos não recebem preenchimento como as mensagens. Só as duas pontas da conversa podem enviá-lo e baixá-lo, com links temporários de 5 minutos.
- Máximo de 25 MB por arquivo. Não geramos miniaturas (não conseguimos: não vemos o conteúdo); o app cria a pré-visualização depois de descriptografar.
O que protege
- Um vazamento do nosso banco de dados ou dos nossos backups: eles só contêm texto criptografado.
- Um funcionário curioso com acesso aos servidores.
- Um invasor passivo na rede, ou qualquer pessoa que intercepte o tráfego.
- As notificações push: elas não levam o conteúdo, então nem a Apple nem o Google o veem.
- A adulteração de mensagens em trânsito ou nos nossos servidores: a descriptografia falha em vez de mostrar um texto alterado.
O que não protege
- A outra ponta é o backend da empresa. É ali que a mensagem é descriptografada. Se a empresa a encaminhar sem criptografia para um helpdesk ou CRM na nuvem, esse fornecedor pode vê-la. Se você trabalha em um setor regulado, pergunte à empresa onde o texto vai parar.
- Nós, agindo ativamente. O seu app recebe a chave da empresa do nosso servidor, e a empresa também recebe a sua de nós. Um operador malicioso poderia substituir qualquer uma das duas. O app fixa a chave da empresa no primeiro contato e avisa se ela mudar, mas isso não protege justamente esse primeiro contato. A impressão digital do link (mais abaixo) fecha essa brecha quando o convite chega por um link gerado com o SDK.
- Um aparelho comprometido. Se alguém controla o seu celular ou o servidor da empresa, pode ler as mensagens ali.
- Os metadados. Explicamos mais abaixo.
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:
- O app só abre um convite de teste se você ativou o Modo de testes em Ajustes → Diagnóstico. Ele vem desativado: um cliente comum nunca vai parar em uma conversa de teste por engano, mesmo que receba o link. Não o ative porque alguém pediu: uma empresa real não precisa disso para falar com você.
- Essas conversas sempre mostram a faixa “Empresa não verificada · ambiente de testes” e nunca o selo de verificada.
- Elas têm limites rígidos: 5 conversas ativas por empresa, 200 mensagens da empresa por dia e convites de no máximo 24 horas. Quando verificamos a empresa, as conversas de teste dela são encerradas.
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:
- O app verifica se a chave da empresa que fornecemos tem a impressão digital
fpdo link. - O app vincula a sua própria chave ao segredo
scom 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.
- Rotação assinada pela chave fixada: aviso discreto (“a empresa renovou a chave de segurança; a própria empresa assinou a mudança”).
- Sem assinatura, ou assinada com outra chave: aviso em destaque. Convém confirmar com a empresa por outro canal antes de continuar. As empresas que não cadastraram uma chave de assinatura sempre fazem a rotação assim.
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.