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

Criei um fluxo de login que autentica uma aplicação front-end (escrita em Vue.js) para recuperar a user_api_key de um usuário do Discourse, seguindo as diretrizes escritas por @sam aqui.

A autenticação funciona, porém minha preocupação está em armazenar a chave privada de forma segura. No momento, a chave privada está armazenada localmente no arquivo .env e é usada para a criptografia/descriptografia do payload. Essa é uma maneira segura de criptografar o payload e, caso não seja, quais são as alternativas para uma aplicação front-end em JavaScript?

Obrigado!

5 curtidas

Como em um aplicativo Electron/Tauri? Não tenho ideia do que você escolheria. Acredito que eles tenham algum mecanismo para armazenamento seguro; talvez, se você tiver sorte, possa usar o Keychain no Mac e algo semelhante no Windows.

4 curtidas

É um aplicativo web, hospedado em um servidor. A preocupação é que, de alguma forma, a carga útil possa ser interceptada se a chave privada for exposta. Estou ciente de que essa é uma preocupação mais geral com criptografia em JavaScript, mas estou perguntando caso exista uma prática mais segura para autenticar um aplicativo web a partir do Discourse.

O sistema de chaves de API do usuário não foi projetado para este caso de uso. Se você vai passar pelo processo de gerar uma chave privada e depois armazená-la no servidor em nome do usuário, por que se dar ao trabalho de toda essa complicação? Basta gerar as chaves no lado do servidor.

É muito difícil para mim fornecer qualquer orientação sem entender completamente qual é o problema real em muito mais detalhes. Por que não simplesmente fornecer pontos de extremidade proxy na sua aplicação web e gerenciar toda a autenticação na sua aplicação?

4 curtidas

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.

Eu também estou curioso sobre isso, já que comecei a usar o software desenvolvido por @owengot. Com base no que @tanius disse, você acha que essa é uma maneira segura de fazer isso, @sam?

Sim, não faça isso. A chave privada é destinada a ser privada por cliente.

Os 10 segundos para gerar a chave são um preço que você precisa pagar. Existem algumas APIs de criptografia em JavaScript que podem torná-la mais rápida.

3 curtidas