【问题标题】:Efficient way to do payload signing in HTML5 SPA在 HTML5 SPA 中进行有效负载签名的有效方法
【发布时间】:2019-08-22 10:06:09
【问题描述】:

我希望实现一些高效(即具有良好性能)的逻辑,以便在我们的 Web 应用程序中进行有效负载签名。目标是让 HTML5 客户端保证接收到的有效负载的内容确实是我们后端生成的内容。

我们不想使用共享 salt 生成有效负载哈希,因为用户可以轻松打开 HTML5 源并找到 salt 短语。

我们现在已经实现了 RSA 签名,我们的后端使用其私钥添加有效负载签名,而我们的 HTML5 客户端使用其烘焙的公钥对其进行验证。然而,签名生成过程需要 250 毫秒(对于相对较小的有效负载),并且由于签名请求的性质,这个时间量是不可接受的。

唯一的另一个想法是在每次客户端初始化与后端的会话时在运行时生成一个共享密钥。然而,这个秘密不能以明文形式发送,所以我们似乎必须实现一个 Diffie-Hellman 交换机制,如果可能的话,我们希望避免这种机制,或者使用现有的库实现自动化。

请记住,由于我们销售产品的性质,保密和加密需要在应用层完成。我们不希望加密我们的流量,这是我们的客户可能会或可能不会实施的东西(因为它是一个 Intranet 应用程序)。但是,我们必须避免将与我们的许可检查机制等相关的内容暴露给他们。后端基于云,并且由我们控制,而是安装在客户的机器上,在本地。

前端是 Javascript,后端是 Java。

【问题讨论】:

    标签: javascript java single-page-application diffie-hellman shared-secret


    【解决方案1】:

    请注意,Diffie-Hellman 交换机制没有保护免受 MITM 攻击,因此不加密流量意味着您需要对来自服务器的 DH 数据进行身份验证。这就是为什么使用基于 DH 的密码套件的 Web 服务器使用其服务器证书的私钥对通过网络发送的 DH 元素进行签名,以便客户端检查这些元素是否真的来自他想要连接的服务器。这些元素是公开的,但需要签名。

    您所说的“使用共享盐生成有效负载哈希”是一个密钥哈希消息身份验证代码,因此它基于共享密钥,正如您所注意到的,并且由于您不想使用此机制,这意味着你不信任客户。因此,您必须使用非对称加密来签署您的有效载荷。

    使用非对称算法对服务器负载进行签名意味着您首先需要让服务器与客户端共享一个公钥。由于客户端和服务端之间没有加密数据,所以需要在客户端源代码中部署服务端公钥。

    您谈到了签名生成过程,但是客户端的签名检查过程在您的情况下也非常重要,因为用户等待结果的总时间是签名时间和检查签名的时间(此外,如果要签名的数据不是动态生成的,则通常可以在服务器上预期签名,但永远无法预期验证)。因此,您需要一种在客户端检查签名的快速方法。首先,签署一个哈希,而不是整个有效载荷。然后在客户端选择您的开发环境中可用的最快的非对称签名算法。请注意,对于对应于相同安全级别的相应密钥长度,检查 RSA 签名比检查 DSA 或 ECDSA 签名更快。所以你应该继续使用 RSA。

    直到这条线为止的所有这些可能对您没有太大帮助!现在有一种方法可以提高性能,使用 RSA 进行签名和验证签名,这种方法与 SSL/TLS 在从同一服务器下载多个页面或其他对象时提高浏览器性能的方法相同:使用会话缓存。您与一个特定用户共享特定会话的公共机密。永远不要将这个公共秘密用于其他会话。当用户第一次连接时,只使用一次 RSA,交换一个临时的共享密钥或交换 DH 材料来创建这个共享密钥。然后,每次服务器需要对一个对象进行签名时,它都会使用这个特定的秘密创建一个密钥散列消息验证码。因此,如果用户发现秘密,例如使用他的浏览器的调试模式,这不是问题:这个秘密只是在这里帮助他知道来自服务器的东西没有被改变。所以用户不能使用这个秘密来改变服务器和其他用户之间的数据交换。

    【讨论】:

    • 答案不适用于我们的用例。用户自己就是我们场景中的攻击者。如果他打开网络并找到共享密钥,他可以重新签署从我们后端发送的有效负载,而不是{isLicensed: false},他可以将其替换为{isLicensed: true},并为该新有效负载提供有效签名,从而改变我们客户端的行为.我知道我们的用例很奇怪,因为本质上我们试图保护自己免受客户的侵害,而不是 3rd 方黑客的侵害。我们唯一可以依赖的就是我们的 Java 字节码加密,其他一切都可以审计。
    【解决方案2】:

    我们最终在客户端和服务器端都使用了TweetNaCl。该库提供了一种简单快捷的方式来进行类似 DH 的共享秘密交换,而无需通过自定义实现。使用临时共享密钥,我们可以轻松地为从 250ms 下降到 10μs 的有效载荷生成散列而不是签名。 RSA 签署初始 DH 交换也很重要,也是我们使用 RSA 的唯一地方。

    请阅读@AlexandreFenyo 的回答,了解有关如何通常处理此类情况的正确理论。

    【讨论】:

      猜你喜欢
      • 2019-08-24
      • 1970-01-01
      • 2015-10-30
      • 2022-10-19
      • 2023-03-06
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 2013-10-18
      相关资源
      最近更新 更多