在软件中加密敏感数据并将其存储/解密在服务器上

信息安全 加密 Web应用程序 密钥管理 数据泄露
2021-09-03 23:52:16

我已经在 IT Security 和 Google 上搜索了类似的内容,但无法找到与我正在做的事情远程相关的任何内容。

我正在开发包含两部分的软件 - 在单个、安全、受信任的计算机上运行的 C# 程序和在服务器上运行的 PHP 软件。该系统处理敏感数据,即药房记录(不在美国,HIPPAA不适用)。

我想安全地加密数据,这样即使在数据库被盗的情况下,也可以尽可能少地解密数据。我已经通过不存储任何可识别的数据(如姓名、地址等)来保护数据,除了电子邮件地址。

我最初想在这个解决方案上使用一个变体,但是经过进一步的思考,我意识到 RSA 不是直接加密明文的合适方法。我的研究使我相信 AES 是最合适的算法。我知道给大多数非加密专家的建议是遵循行业标准协议,但是我找不到符合我标准的协议。

标准是:

  • 对于每个用户的数据,在给定服务器内容的情况下,只有用户自己应该能够在数学上访问他的数据——这意味着使用从他的密码派生的密钥(C# 软件可以完全访问所有用户的数据,它可以访问到钥匙)
  • 仅获得服务器的内容就不可能解密
  • 明文数据永远不应该存储在服务器上(因此我想在 C# 软件中加密)
  • 数据需要能够在没有用户提供密码的情况下进行加密
  • 数据只会在 PHP 中解密和读取 - 不需要重新加密和写入新数据或修改过的数据
  • 只能存储或访问用户密码的哈希值

这是我想出的一个解决方案:

自然,所有连接都是通过 TLS/SSL(通过 HTTPS)进行的。在传输任何敏感数据之前,服务器和软件会“准备好”或配对。在服务器上生成一个非对称密钥对,并将私钥传输给软件(我将 C# 组件称为“软件”)。私钥从服务器中删除,公钥被存储。

当用户注册时,他们的密码用于使用 PBKDF2 生成一个 128 位密钥。此密钥使用先前生成的公钥进行 RSA 加密并存储。

当数据从软件上传到服务器时(每 24 小时),软件会发送一个用户 ID 列表,它将为其上传数据(当然是通过 HTTPS)。服务器发回 RSA 加密的 128 位密钥列表以及相应的用户 ID。该软件使用其私钥一一解密,获得 128 位密钥列表。对于每个用户,服务器获取该用户的数据并使用该用户的相应密钥使用 AES-128 对其进行加密。整个有效载荷上传到服务器并直接存储。

当用户登录时,他们的密码可以在短时间内访问,并且 PBKDF2 用于生成他们的 AES-128 密钥。为了防止他们在每次加载页面时都必须重新输入密码,AES-128 密钥存储在他们机器上的安全 cookie 中,有效期很短(5-10 分钟),并用于后续页面加载以解密和显示该用户的数据。它实际上并没有在任何时候存储在服务器上。

这个安全协议合适吗?我应该修改它吗?有什么符合行业标准并且可以在这里工作的东西吗?任何帮助将不胜感激。

1个回答

推出自己的协议很难您将很容易拥有或多或少运行的东西,但是获得同样安全的东西将需要大量的工作和大量的运气。

根据您的要求,您需要一个如下所示的协议:

  • 每个用户都有一个非对称密钥对,适用于加密(例如 RSA 或 ElGamal)。
  • 私钥K priv使用从用户密码导出的对称密钥K加密,然后存储在服务器上。
  • 公钥K pub存储在服务器上,没有加密(它是public)。
  • 数据元素使用K pub加密。任何人都可以用公钥加密任何东西(这就是公钥是公开的)。
  • 要解密数据,用户输入他的密码,该密码用于重新计算K,然后解密包含K priv的 blob 。使用该非对称私钥,用户可以解密所有已使用相应公钥加密的数据文件。

OpenPGP 格式包含所有需要的原语。BouncyCastle是一个可以使用该格式的开源库,它是 C#/.NET 版本。