用于用户身份验证的 Javascript 有效负载加密安全方法

我已经创建了一个登录流程,用于对前端应用(使用 Vue.js 编写)进行身份验证,以获取 Discourse 用户的 user_api_key,该流程遵循 @sam 在此处 链接 提供的指南。

身份验证功能正常,但我担心的是如何安全地存储私钥。目前,私钥存储在 .env 文件中,并用于加密/解密有效载荷。这种方式是否安全?如果不安全,对于前端 JavaScript 应用,有哪些替代方案?

谢谢!

就像在 Electron 或 Tauri 应用中那样吗?我不确定你会选择什么方案。我猜它们应该都有某种安全存储机制。如果你运气好,在 macOS 上可以使用钥匙串(Keychain),在 Windows 上也有类似的方案。

这是一个托管在服务器上的 Web 应用程序。主要担忧是,如果私钥泄露,载荷可能会被拦截。我知道这是 JavaScript 加密的一个更普遍的问题,但我想询问一下,在 Discourse 中认证 Web 应用程序是否有更安全的做法。

用户 API 密钥系统并非为此用例设计。如果你费尽周折生成私钥,然后又在服务器上替用户存储它,那何必多此一举?不如直接在服务器端生成密钥。

如果不更详细地了解实际问题的具体情况,我很难提供任何指导。为什么不直接在 Web 应用中提供代理端点,并在应用内处理所有认证呢?

在与我的同事 @owengot 讨论后,以下是该问题的更详细描述。

这是一个基于 Vue.js 的 Web 应用程序,它没有自己独立的服务器端组件。相反,它是一个独立的 Web 应用程序,使用 Discourse API,因此在某种意义上,Discourse 充当了服务器。使用场景包括独立的投票或表单,其中内容会以用户账户的名义发布到 Discourse 主题中。能够创建此类软件而无需自定义服务器端组件,似乎对于这些用例来说是一种不错的架构,因此理想情况下我们希望避免任何“服务器端”操作。

现在,获取 User-API 密钥可以按预期工作,但 @owengot 发现,在 JavaScript 中生成私钥的步骤非常耗时(长达 10 秒,这在 JavaScript 中效率很低……)。随后,他发现了一个技巧:同一个私钥可以用于多个用户,因此他将该私钥存储在 Web 主机上的一个文件中,该主机也提供 Web 应用程序的其他静态文件(JS、CSS 等)。这样确实很快……但现在这个私钥(1)是共享的,并且(2)以公开的 URL 形式存储,暴露在公开环境中。这听起来,嗯,令人担忧 :fearful:

因此,我说我们必须向 Discourse 团队咨询这种技巧的安全影响。我看到两个基本替代方案:

  • 如果该私钥“仅”用于有效载荷加密,那么我们可以接受这种情况,因为我们的通信也通过 SSL/HTTPS 进行了加密。

  • 但是,如果知道该私钥能够以某种方式计算出随后用于在某个人的 Discourse 账户下发布内容的 User-API 密钥,那么这种技巧显然是不可接受的。

我也对此很好奇,因为我已经开始使用 @owengot 开发的软件。根据 @tanius 的说法,你觉得这样做安全吗,@sam

是的,千万不要这样做。私钥本应为每个客户端单独生成并保密。

生成密钥所需的 10 秒时间是必须付出的代价。不过,有一些 JavaScript 加密 API 可以加快这一过程。