如何安全地存储加密的用户数据并仅向正确的用户提供服务?

5
假设我必须存储用户的敏感数据,这些数据在客户端可以选择加密。
  • 加密(可选)应使用用户的密码口令进行。
  • 用户登录(可选)应使用用户的登录密码进行。

备注:
明文密码不会存储在服务器上或通过网络传输。

我的选项及其缺点:

1. 无身份验证,客户端授权:
服务器向所有人提供数据,但只有原始用户才能解码。
数据可以被任何人用来尝试破解加密 - 并不是最好的保护方式。

2. 服务器端身份验证,无授权:
服务器存储用户密码以访问数据,并仅向提供正确密码的用户提供数据。
用户不相信没有加密的网络传输他们的数据。

3. 身份验证和授权:
服务器存储用户密码以访问加密数据,加密使用与用户密码不同的密码口令。
安全性较高,但用户不想记住两个密码

4. 身份验证 vs. 授权: 服务器存储用户密码以访问加密数据,加密使用相同的密码。
用户很满意。存在一些安全问题。

我更喜欢第四个选项,但我的担忧是:
如果服务器被攻击,我怎么能确保加密密码和加密数据不能一起使用来破解加密? 如何使破解加密更困难?

一些想法:

  • 为密码和数据使用不同的加密算法。
  • 在加密之前向用户的密码添加固定字符串。
  • 将用户的密码填充到一定长度。

编辑:

该系统应与备份系统非常相似,应从各个方面保护安全性:服务器不应能够读取数据,只有原始客户端才能访问数据,并且应防止中间人攻击。因此,如果有人入侵了服务器身份验证或客户端加密,则不应泄露数据。

它应该是基于Web的,因此可以通过HTTPS防止中间人攻击。

为了防止服务器入侵揭示数据,数据在客户端进行加密。

为了防止客户端加密被篡改,应在服务器端使用某些登录和密码或令牌(可能是唯一的URL)来保护对数据的访问。

3个回答

7
@Vitaly,在我回答之前,请允许我澄清一些术语,因为您似乎对某些术语的使用方式与通常的不同。
身份验证-证明你是谁的过程(更准确地说,证明你拥有所声称的身份)。 授权-用于限制、控制和授予访问权限的机制。 加密-一种保护数据的机制,即使有人可以访问该数据也无法破解。
现在,让我重新表述你的选项,然后我会建议其他内容:
1.无身份验证、无授权、客户端加密 2.服务器端身份验证、服务器端授权、服务器端加密 3.服务器端身份验证、服务器端授权、客户端加密 4.使用服务器凭据的服务器端身份验证、服务器端授权、客户端加密
现在,我认为每个选项的位置可以更清晰。一般来说,你真的想遵循“最佳实践”(不要让我开始这些)原则中的“深度防御”,即不仅使用加密或访问控制,而是同时使用两者!但是,正如你指出的那样,这可能与另一个原则“保持安全简单”相矛盾(如果用户需要记住两个密码)。
没有试图太烦人,你没有提供关于你的环境的太多信息。例如,这是一个Web应用程序吗?如果是这样,为什么SSL/TLS的加密不足以满足你的需求?还是说这是用户上传个人数据,你(和你的系统)也不应该看到(例如备份类型服务)?在这种情况下,客户端加密将是必要的。
因此,(最终)根据您的环境/要求,我提出了以下选项:
  1. 如果可以的话,请使用安全协议(例如SSL/TLS)进行加密。使用服务器端身份验证+授权、协议加密。
  2. 如果您的系统需要进一步保护这些数据,例如信用卡信息(请注意我目前不是PCI:QSA;),请使用上述选项,并使用由服务器生成的加密密钥(而不是密码)进行服务器端加密(当然要保护好密钥)。
  3. 如果需要保护数据免受您的系统攻击,则需要在服务器端身份验证+授权(重申您的第3个选项)之外进行客户端加密。
    但是,您不一定需要强制用户记住额外的密码/短语。再次根据您的环境,您可能可以考虑在客户端存储某种形式的密钥,例如用户证书存储库/密钥环中的证书,甚至存储在受保护的配置文件中;基于生物识别数据的密钥(不容易,但我已经成功看到过这样做,尽管它有自己的问题),通过手机等方式进行密钥分发等。这将使您能够使用强大的密钥,防止服务器访问这些密钥,不需要用户记住两个密钥,并且不会在不同的上下文中为不同的用途重复使用单个密码。

2
另外一个要点是,用户的密码不应该以明文形式存储,而应该进行哈希。但是,将密码用作加密密钥会要求使用它作为明文!此外,在重用相同的密码时更改算法也无济于事,请勿忘记柯克霍夫定律。 - AviD
1
@Vitaly,你提出了两个非常好的问题:1.是否存在可以利用相同密钥(或使用密钥加密的数据和以哈希形式可用的密钥)的密码分析攻击?我真的不知道,但我认为一个强大的SALTED哈希应该足以保护加密密钥。 - AviD
1
第二个问题,实际上更有趣的是,分享密钥是否存在其他问题?例如,如果坏人可以暴力破解登录页面,从而发现密码/密钥。或者,如果您使用简单的哈希函数,坏人可以访问数据库,他能否通过彩虹表找到用户的密码/密钥?显然,这两个问题都可以通过采用强密码策略和限制错误登录次数的锁定机制来防止(对于第一个问题),以及使用加盐哈希函数来防止(对于第二个问题),但这确实显示了潜在的问题。 - AviD
1
(续)例如,一个恶意管理员可以在哈希之前,在用户登录过程中嗅探/调试用户的密码。另外,当用户想要/需要更改密码时会发生什么?难道你真的要重新加密他的所有数据吗?当然,还有其他策略来解决这些问题,但实际上没有充分的理由这样做。加密密钥和密码应该始终是单一用途的。 - AviD
1
我认为密码和授权被高估了,它们要比大多数人想的更难正确实现。 - Omnifarious
显示剩余7条评论

3
您可以了解一下零知识协议,特别是安全远程密码协议,它使得基于密码的身份验证无需将密码透露给服务器成为可能。这样就可以使用相同的密码进行身份验证和派生数据加密密钥。 此外,您还可以查看Clipperz在线服务,该服务实现了类似于您需求的功能,并且是开源的。

1

使用第一种选项,使数据的URL包含一个长随机字符串。任何知道该随机字符串的人都可以获取数据。当然,只有创建数据的客户端才能立即拥有该URL。

如果有人想要给别人可撤销的访问权限,则允许他们生成一个新的随机URL,并提供一种方式来命名该随机URL并撤销其访问数据的能力。

基于能力的安全更容易正确实现,更灵活,并且对用户更有意义。有一个关于基于能力的安全的非常优秀的YouTube视频和一个关于它的一些文章的不错的网站


我也考虑过这个选项,但是有人丢失URL的问题非常棘手。我甚至考虑通过电子邮件将URL发送到注册的电子邮件地址。但是如果有人丢失了URL并且他的电子邮箱无法访问,我仍然无法承受数据丢失的风险。 - m_vitaly
@Vitaly Polonetsky:当然,他们也可能会忘记密码。 :-) - Omnifarious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接