网络消息应用程序的非对称/端到端加密

信息安全 加密 公钥基础设施 密钥管理 RSA 客户端
2021-08-26 06:09:15

背景

我正在尝试为消息传递设计一个安全且可持续的网络应用程序。目的是学习如何创建安全的 Web 应用程序。

假设应用程序是用 JavaScript 编写的,用于基于 Web 的客户端,而 PHP 用于服务器端。

使用 Web 应用程序的客户端将登录,以便能够在各种设备上使用该服务。

然后,客户端可以安全地向其他用户发送消息,而无需任何中间人能够以明文形式阅读消息。我也不希望服务器能够读取消息,因此主要加密必须在客户端进行。


想法

  • SSL/TLS - 确保与服务器的有效通信
  • RSA - 非对称加密 - 用于加密加密密钥
  • AES - 加密未知数量的数据,最常见的是纯文本

整个应用程序显然将使用 SSL / TLS 构建,以允许客户端和服务器之间进行安全且经过验证的通信。

为了确保只有目标方可以访问发送的数据,使用了非对称加密。每个客户端都有自己的私钥存储在客户端,他们的公钥存储在服务器上附加到数据库中的用户身上。

当 Alice 想给 Bob 写一条消息时,她使用强 AES 密钥对数据进行加密——因为 RSA 只能处理有限的数据大小。为了确保只有 Bob 可以阅读该消息,她从数据库中检索 Bob 的公钥并用它加密她生成的 AES 密钥。然后将加密的消息连同使用的密钥一起发送到服务器,并用 Bob 的公钥加密。

Bob 从服务器检索此消息/密钥对。由于 Bob 拥有与使用的公钥相关的私钥,用于加密 Alice 的消息密钥 - 他并且只有他可以以纯文本形式检索使用的密钥。然后,他可以使用这个未加密的密钥解密主消息并将其作为纯文本读取。


关注点

公钥和私钥对必须在服务器端生成。这会强制将私钥发送给用户以供使用。这怎么能保证安全,因为任何中间人都可以检索私钥以进一步用于解密 Alice 的所有消息。

为了确保服务器不知道用户发送了什么消息,它不能访问/存储私钥。这迫使密钥存储在客户端 - 使用 Javascript,一种很少与安全性或安全数据持久性相关的语言和平台。由于安全性是我主要关心的问题,因此无法正确存储私钥是一个主要问题。

假设用户想从另一台设备登录并使用该应用程序,那么私钥也必须“神奇地”出现在那里。无论如何都强制服务器存储私钥。还有其他方法可以进行此加密/密钥管理吗?


澄清问题

如果上述主题太长而无法阅读、令人困惑或您只是赶时间,以下是简化的问题。

如何确保在它们之间发送的消息只能由这两方阅读?

我如何确保我的用户/服务器或其他任何人可以阅读他们的消息?

如果他们是在客户端安全地存储私钥的一种方式,那有多糟糕?

2个回答

我认为您的方案还有一个额外的问题/挑战:除了服务器生成密钥对的问题之外,该方案还允许中间人攻击:A 要求 B 的密钥,服务器用他的回答拥有自己的密钥 C。现在服务器可以再次为 B 解密、读取和加密,并将新的密文发送给 B。只要使用服务器完成通信,A 和 B 都不会注意到。为了防止这种情况,您需要将密钥管理服务器和消息服务器解耦。在最好的情况下,您将使用一个活跃的社区密钥服务器,例如用于 pgp 的那些。

无论如何,假设密钥管理是诚实的,你的混合加密应该可以解决。

关于密钥生成,请查看CryptoJS如果我没记错的话,它(几乎)是一个成熟的加密框架,也可以生成密钥。您可以使用 html5 的本地存储 API来存储密钥客户端。

如果您想保证完全保密,即消息只能由收件人阅读,您将需要使用端到端加密。单独的密钥和消息服务器很好,但只需要一两个法院命令就可以让它们串通。

真实性至少同样重要。拥有世界上最好的保密性并不能保护您免受相当于3way 恶作剧电话的伤害。唯一确定的方法是亲自交换密钥。例如,Signal 消息应用程序使用“安全号码”来执行此操作。