【问题标题】:where to store SHA256 key pair per user每个用户在哪里存储 SHA256 密钥对
【发布时间】:2021-04-11 16:29:41
【问题描述】:

我在 NodeJS 中有一个数据库和一个 API,我使用 Web 应用程序创建用户,每个用户都可以创建/更新/删除数据。

为了确保这一点,我需要加密用户的数据。所以我想要的是在每次创建用户时创建一对 SHA256 公钥私钥。

实际上我所做的是将这些密钥存储在数据库中,通过使用全局 SHA256 密钥对对其进行加密。

所以,简而言之,我有一对全局密钥来加密每个用户的每对特定密钥。

事实上,这似乎并不安全,因为最终每个用户都有自己的加密/解密方法存储在数据库中。

例如我可以有 2 张桌子:

User table :

id_user | firstname | lastname | encrypted_data
-----------------------------------------------
1       | John      | Doe      | QMwmuCMmI..
2       | Jane      | Doe      | QMwmuCMmI..
... 

Keys table :

id_user | public    | private
------------------------------
1       | MIICIjA.. | MIIJrT..    
2       | MIICIjA.. | MIIJrT.. 
...   

所以从John Doe 到他的公钥和私钥的链接很简单。

一个问题是我不能要求用户创建一对私钥/公钥并只向我发送公共密钥,因为所有这些都需要是自动的,用户不必做任何事情。

另一个问题是应用程序应该可以在任何设备上使用,所以私钥不能存储在客户端。

【问题讨论】:

  • 1. SHA256 是一种单向哈希函数,它与公钥或私钥没有直接关系。没有 SHA256 密钥对这样的东西。 2. 是的,这是一个问题,将数据加密密钥与密文存储在同一个数据库中不会提供任何安全性。也许加密数据库所在的存储就足够了。
  • 那么加密服务器?数据库的 URL ?事实是存储的数据必须加密,所以无论如何我都需要一些东西来直接加密数据并在客户端或在发送之前对其进行解密。
  • 使用密码作为加密密钥是否足够安全?密码不以纯文本形式存储,并且不可解密。那么解密数据的唯一方法就是知道密码?
  • 加密是一种防止向各种系统实体泄露的机制,这些实体会根据所使用的加密类型和位置而变化。为什么需要加密?这是某种合规要求吗?您的合规官对此有什么建议吗?
  • 用户数据必须加密,每个用户的数据必须用不同的密钥加密是完全不同的要求。我不熟悉法国的管辖权,但我想第一个就足够了。很难推断出云服务提供商无法通过某种努力获取数据的加密方案。我知道的唯一方法是完全同态加密,没有人使用,因为它太慢而且仍然可能存在一些边信道漏洞。

标签: node.js encryption


【解决方案1】:

您不能将它们存储在服务器上,因为攻击者在服务器上。恶意黑客可以轻松找到密钥(因为它们未加密),下载整个数据库并解密所有内容。

因此,您最好的选择是将密钥存储在完全不同的机器上,并让该机器进行加密和解密。这样,攻击者首先必须闯入您的机器,然后再进入加密/解密机器。并非不可能,但希望更难。

基本上,没有什么是不可破解的。为攻击者制造尽可能多的困难是可行的方法。

此外,即使您必须将数据严格存储在主服务器可以访问的数据库中,也请不要将它们存储在同一个表中(如您的示例中所示如何保存它们在单独的表格中)。保持添加到用户数据库的所有数据的索引相同,以便用户数据库的索引 1 将为该索引生成正确的键(正是您所做的)。

另一种选择是加密硬件。我对此并不熟悉,但我知道有些公司销售的硬件可以满足您的所有加密需求。

【讨论】:

  • 在其他机器上存储实际上是我为保护它多一点的方式。但是这台机器不能进行加密和解密,除非这意味着数据被解密的多个请求。所以我送钥匙。您为什么建议使用其他服务器加密和解密数据。
【解决方案2】:

免责声明:此答案公开了两种保护用户数据的解决方案,但从等式中排除了 SHA256 公钥/私钥(我相信,更安全的东西)。这可能不是一个可接受的解决方案。

“简单”方式

我相信 Termius 就是这样做的。在这种情况下,您将使用密码来保护帐户访问和加密数据。

你最终会在数据库中得到类似的东西:

  • id
  • email/username
  • password_hash(保护帐户访问权限)
  • ... 尽可能多的字段,使用对称算法(即 AES)使用 unhashed 密码对值进行加密

优势:

  • (可选)端到端加密
    而不是在服务器端进行解密,而是将加密数据按原样发送到客户端。客户端应用负责在可视化之前进行解密,并在将所有内容发送回服务器之前对其进行加密。

缺点:

  • 潜在的数据丢失
    如果用户丢失了密码,他也会失去对所有数据的访问权限。
  • 加密密钥存储在数据库中
    当然,它是散列的。如果散列算法足够强大,它可能在相当长的一段时间内都足够安全。但是对于一些 3 字母机构来说,它可能会相对较快地逆转?‍♂️

警告:

  1. 不要使用密码散列作为密钥,只使用未散列的密码。否则,加密密钥将“按原样”存储在您的数据库中(password_hash 字段)。
  2. 在计算密码哈希时始终使用 salt(在 2021 年这样说听起来很明显,但我还是更愿意这么说)

更强大的加密

我相信这就是 ProtonMail 加密其用户数据的方式。

创建Protonmail账户时,需要提供两个密码:第一个用于账户登录,第二个用于数据加密。

优势s

  • 您根本不需要在数据库中存储第二个密码(无论是否经过哈希处理)。

如果数据无法解密,说明第二个密码(也就是加密密钥)不正确,就这么简单。

  • (可选)端到端加密
    与“简单方法”中描述的相同。

缺点:

  • 潜在的数据丢失
    如果用户丢失了第二个密码,他也会失去对所有数据的访问权限。如果他丢失了它的第一个密码,那么他就失去了对“身份验证”的访问权限。典型的“我忘记了密码”流程在这里有效,不会引发与加密数据相关的任何问题。

衡量利弊

这两种解决方案都有一个主要缺点:潜在的数据丢失。

如果您选择类似 Protonmail 的解决方案,我会说这个缺点被一个主要优势所弥补:用户是其数据安全性的唯一参与者,您不会在数据库中存储有关加密密钥的提示。因此,如果您使用行业标准的加密算法,您根本不负责。黑客除了暴力破解每个用户的加密密钥外别无他法。

另外,如果您让用户了解丢失密码的后果,您还可以声称自己 100% 无法同时访问他们的数据。这是最高级别的数据隐私,这就是世界需要恕我直言(无论我们谈论的是哪种类型的数据)。

【讨论】:

  • 这些解决方案对我来说并不是最好的。用户正在存储敏感信息,因此数据不可能丢失。您是否建议其他类似@divinelemon 的解决方案?
  • 您可以使用 [Shamir 的秘密共享|en.wikipedia.org/wiki/Shamir's_Secret_Sharing] 算法添加一些密钥恢复系统。首先,生成一个秘密和一堆共享。然后,存储加密密钥的加密版本(也称为密码或第二个密码,具体取决于您要使用的解决方案)。最后,向用户显示共享(这与 MFA 中使用的恢复代码相同)。在密码恢复时,请求 2 个或更多共享,解密数据,请求新密码,使用新密码加密数据并重做密钥/共享生成的整个过程。
猜你喜欢
  • 1970-01-01
  • 2015-05-04
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 2012-09-06
  • 2013-02-19
  • 2019-03-10
相关资源
最近更新 更多