Forma segura de criptografar payload em Javascript para autenticação de usuário

Depois de conversar com meu colega @owengot, aqui está uma descrição mais detalhada do problema.

Existe um aplicativo web baseado em Vue.js que não possui um componente ativo próprio no lado do servidor. Trata-se, na verdade, de um aplicativo web autônomo que utiliza a API do Discourse, de modo que, de certa forma, o Discourse atua como o servidor. Os casos de uso incluem enquetes ou formulários autônomos, nos quais o conteúdo é publicado em tópicos do Discourse sob a conta do usuário. A possibilidade de criar esse tipo de software sem componentes personalizados no lado do servidor parecia uma arquitetura interessante para esses casos, então, idealmente, gostaríamos de evitar qualquer coisa “no lado do servidor”.

Agora, obter uma chave de API de usuário funciona conforme o esperado, mas @owengot descobriu que a etapa de gerar uma chave privada em JavaScript leva muito tempo (até 10 segundos, pois é simplesmente ineficiente em JavaScript…). Depois, ele descobriu a “gambiarra” de que a mesma chave privada pode ser usada para vários usuários, então ele a armazenou em um arquivo no servidor web que também serve os outros arquivos estáticos do aplicativo web (JS, CSS etc.). Isso torna o processo rápido… mas agora essa chave privada é (1) compartilhada e (2) armazenada de forma aberta, com um URL publicamente acessível. Isso parece, hum, assustador :fearful:

Então, eu disse que precisamos perguntar à equipe do Discourse sobre as implicações de segurança dessa “gambiarra”. Vejo duas alternativas básicas:

  • Se essa chave privada for usada “apenas” para criptografia de payload, poderíamos aceitar isso, pois também temos a comunicação criptografada via SSL/HTTPS.

  • Mas se saber essa chave privada permitir, de alguma forma, calcular a chave de API de usuário resultante, que depois é usada para publicar na conta de alguém no Discourse, isso tornaria, naturalmente, essa “gambiarra” inaceitável.