我需要创建一个 PHP Web 应用程序来存储一些用户输入的数据。这些数据应该只对系统的某些选择性用户(包括创建它的用户)可读。这些数据不应该被服务器管理员或其他后端管理员解密。只有最终用户才能解密数据。
我确实知道 HTTPS/TLS 将安全地加密客户端和服务器之间的数据,但我的要求是只有一些选定的最终用户应该能够读取数据。我也知道这里的浏览器是通信的终点。因此,在研究中,我想到了使用私钥/公钥对进行端到端加密的概念。所以我的问题是是否可以在使用 PHP 的 Web 应用程序中实现这一点。
我需要创建一个 PHP Web 应用程序来存储一些用户输入的数据。这些数据应该只对系统的某些选择性用户(包括创建它的用户)可读。这些数据不应该被服务器管理员或其他后端管理员解密。只有最终用户才能解密数据。
我确实知道 HTTPS/TLS 将安全地加密客户端和服务器之间的数据,但我的要求是只有一些选定的最终用户应该能够读取数据。我也知道这里的浏览器是通信的终点。因此,在研究中,我想到了使用私钥/公钥对进行端到端加密的概念。所以我的问题是是否可以在使用 PHP 的 Web 应用程序中实现这一点。
您当然可以实现一个使用端到端加密并使用 PHP [1]编写的服务器部分的系统。您只需将加密部分实现为在“端”上运行的东西 - 即浏览器,因此实际上您需要在 JavaScript 中实现它 - 您的 PHP 代码会将这个 JS 提供给端点。PHP 代码还需要为每个应该有权访问被加密数据的人提供公钥[2] 。根据您将如何存储私钥,PHP 可能也会存储(并提供)这些私钥的“包装”(即加密)版本。
整个项目的服务器端 (PHP) 部分最终会比典型的 Web 应用程序稍微复杂一些。它需要能够对用户进行身份验证,这是正常的,但没有启用管理员模拟用户(这不正常)[3]。它可能需要能够存储(和控制访问)每个用户的私有数据(封装的密钥)、每个用户的公共数据(公钥)和受限访问共享数据(实际加密的用户数据)。根据存储的数据类型、数据量、您是否需要能够在事后调整谁可以访问数据以及是否需要任何类型的可搜索性,您可能会遇到任何许多额外的复杂性。安全的端到端系统很难。[4]
不过,这件事情的客户端(JS)部分将是繁重的工作发生的地方,虽然是加密的。这有点尴尬,因为 JS 不擅长加密。存在标准加密函数的纯 JS 实现,但它们往往存在问题(例如相对较慢,并且可能暴露侧信道漏洞,例如定时攻击)。一些浏览器支持使用来自 JS 的数据执行本机加密操作,这更快、更安全(假设您信任浏览器开发人员,您在这里需要这样做),但它还不是通用的。
[1] 你可能不应该。对于任何高度安全敏感的代码来说,PHP 都是一个糟糕的选择,因为它相对容易犯安全错误。(现代的、完全修补的)PHP 中的安全代码当然是可能的,但我建议使用能够实现它的语言更难自己动手,比如 Java、C#、VB.NET,或者 Go 或 Python。
[2] 这提出了一个安全漏洞,您需要找出解决方法,因为端点系统 - 用户和他们的 Web 浏览器 - 无法判断是否发送到客户端的公钥(数据正在被加密到客户端) ) 是正确的公钥。恶意服务器管理员可以将自己的公钥添加到密钥列表中,然后恶意管理员可以读取使用该密钥列表加密的任何数据。您需要某种方式来验证密钥的真实性。
[3] 这里有一个棘手的问题是,虽然服务器永远不应该存储用户的密码,但服务器通常会在创建帐户时以及无论何时使用密码(登录、更改密码等)时都会简要地看到密码。 )。恶意服务器管理员可以修改服务器以窃取此密码。如果该密码是作为该用户登录所需要的全部 - 例如,如果知道用户的密码允许您解开用户的私钥 - 那么恶意管理员可以解密他们不应该访问的数据通过冒充合法用户。
[4]老实说,对于在信息安全和开发人员方面更有经验的人来说,这听起来像是一个项目。这不是一个简单的问题,加密也很难做到正确。
如果系统管理员必须无法读取数据,则无法在 PHP 中实现它,因为它在服务器上运行。
在这种情况下,私钥不能在服务器上,因为管理员总是有办法访问它。
我认为实现目标的最佳方法是使用用户输入的密钥加密/解密浏览器中的数据(使用 Javascript)。
浏览器中的端到端加密是不可能的,因为客户端应用程序(JavaScript)由服务器提供服务,而服务器管理员(或任何第三方脚本)可以轻松地污染提供的脚本并窃取客户端生成的所有秘密。没有办法解决这个问题。端到端意味着您不必信任任何中央机构,包括传输加密有效负载的服务器,但在这种情况下,您的服务器就是这样 - 一个中央机构,在每个页面加载时将客户端程序分发给您的用户,并且您的用户必须相信它不会污染客户端程序。
因此,您将需要一个独立于任何受信任方的、从社区审查代码的源代码构建的单独客户端程序。因此,您的 E2E 应用程序不能是 Web 应用程序。但是只提供加密有效载荷的服务器端部分可以用 PHP 实现。