使用 cryptojs 的最佳选择是什么,将密钥存储在客户端和服务器端,或者生成密钥并将其以某种方式传递给另一端?

What's the best option using cryptojs, have the key stored in client and server sides, or generate the key and pass it some way to the other side?

我想使用 cryptojs 加密和解密在客户端和服务器之间传递的数据。要解密数据,必须知道使用的密钥,所以我有两个选择:

在这两种情况下,如果请求被捕获,您可以将其重新发送到服务器并访问页面。

如果我用的是固定密钥,如果你拿到密钥,就可以解密所有消息,除非你更改密钥。

如果我把密钥和数据一起传递,你就得到密钥和数据(我传递的方式不明确,所以你必须知道哪部分是密钥,哪部分是数据)。但是这个密钥会随着每个请愿书而改变。

无论如何,我认为攻击者可以只看到客户端代码并发现用于加密数据的过程并执行相反的过程。

最好的选择是什么?

PD:我知道 https 是方式,但我希望 tp 也这样做。

选项:1

假设你想使用CryptoJS并且你想使用HTTP,并且你不想让攻击者知道秘钥,你可以使用PBKDF2.

PBKDF2 is a password-based key derivation function

您可以从浏览器上的用户密码生成一个密钥,并用它来加密数据加密密钥。

在服务器端,假设您可以从用户数据库访问用户密码,您可以使用该密码重新生成相同的 PBDKF2 密钥并解密数据加密密钥。

一旦服务器和客户端就共享数据加密密钥达成一致,他们就可以使用该密钥进行未来的数据交换。在此过程中,黑客可能无法访问以加密形式交换的数据加密密钥。此外,它需要人工输入黑客不知道其值的密码。

注意 1:如果您根据第三方身份验证提供商对用户进行身份验证并且您无权访问用户密码,则此解决方案将不起作用。

注意 2: CryptoJS 似乎只支持对称密码 - 因此,需要在客户端和服务器之间交换密钥。必须通过共享密钥交换密钥,该密钥未使用将使用密钥的相同通道共享。

选项:2

如果您由于某种原因不能使用 PBDKF2,并且仍然希望在客户端和服务器之间安全地交换密钥,那么,您将不得不采用非对称加密。库 JSEncrypt 提供 RSA 加密。

如果使用这个库,那么,客户端(浏览器)可以使用 CryptoJS 生成一个密钥,并使用 JSEncrypt 使用 RSA public 密钥对其进行加密,并将加密后的密钥发送到服务器。服务器可以使用 RSA 私钥解密加密密钥。此过程将导致安全的密钥交换。