目标:
我希望允许用户在自定义web应用程序(PHP/MySQL,在靠岸的托管环境中)中创建问题并收集其他用户的信息,并保护收集到的数据。
背景:
所有用户所回答的默认问题都很笼统,不能被解释为个人可识别信息( PII ),从而限制了我保护它的责任,但是创建自己的问题的用户可能会要求PII,而PII则成为一种责任。
我想要做的是以这样的方式保护这些信息:如果主机帐户或数据库被破坏(或者两者都被破坏),如果没有大量的工作,PII就无法恢复,即使这样,理论上也只能恢复一小部分。
提出的解决方案:
假设MySQL的内置AES_ENCRYPT()/AES_DECRYPT()函数用于加密PII表,则密码需要存储在托管帐户中,因此如果主机帐户受到破坏,数据就可以轻松读取。
由于用户的密码受到很好的保护(使用salt哈希),我正在考虑在身份验证过程中捕获他们的明文密码,对其进行加密,并将其存储在PHP会话中,直到用户注销为止。
将为每个用户创建一个公钥/私钥组合,私钥由用户的密码+ salt保护。
然后,当基于用户自定义问题的PII数据添加到DB中时,用户的公钥将被用于加密他们通过应用程序收集的PII。当数据被读取时(仅当用户登录时),数据将用用户的私钥(用他们的密码+salt解锁)解除加密。
我看到的利益是:
在最坏的情况下,服务器完全受损,读取应用程序代码查找加密密钥,对PHP会话文件进行解密以查找用户的密码,然后对与该用户关联的PII表中的条目进行解密,然后只能恢复从当前登录用户的问题中收集的PII。没有登录的任何用户都是安全的。
。
我看到的的缺点是:
。
我的问题是:有更好的方法吗?
发布于 2011-09-01 15:55:13
我从安全的角度看这个设计有很多问题。首先,密码绝不能加密,这是CWE-257发现的漏洞。
此外,MySQL的AES_ENCRYPT()完全是垃圾,原因不止一个。它使用EBC模式,下面是一个很好的例子来说明为什么这是垃圾:
原始图像:

EBC模式(这是mysql的AES_ENCRYPT()使用的):

但是,如果受攻击的数据库,攻击者将通过启用AES_ENCRYPT()来击败query log。
应该避免使用用户的密码进行加密,您应该使用密码密码。如果您确实使用了密码,请确保使用String2Key函数。您还必须在random iv中使用CBC或CMAC模式。我看不出非对称密码学有多大帮助。非对称密码学速度慢,内存密集。当攻击者控制消息时,它们保护的数据就变得不那么安全了,因为您可以比较密码文本消息。这就是为什么随机的IV is important,在不对称的世界里,你没有这个级别的保护。
密钥生成应该类似于:$key=string2key($base_nonce.$salt.$user_password)
确保您的string2key函数的输出与您的键空间大小相同。所以aes 128需要128位密钥。每个密码都应该有自己的$salt,$base是一个存储在文本文件中的加密密码。(攻击者在破解密钥之前必须读取该文件,如果这个值很大,比如128位,那么它就是一个模拟点。)每个消息都需要它自己的$iv,并且这个值也必须是一个密码名(类似于salt)。我将从$salt、$iv和$base_nonce中生成/dev/urandom。IV可以与密码文本一起存储在数据库列中的纯文本中。
从法律的角度来看,即使您构建了一个安全的加密系统,您仍然存在内部威胁的问题,如果服务器被完全破坏,所有的数据仍然会被破坏。这真的不是一个工程问题。
对抗法律威胁的最佳辩护是由熟练律师撰写的强有力的条款和条件。
发布于 2011-09-01 13:37:20
我会担心的是以下几点。“任何未登录的用户都是安全的”部分太乐观了。通过使用用户的密码保护私钥,您可以对各种密码进行强制攻击。不仅是现在的会议,而且是所有人。一种有效的方法是简单地列举前100个常用密码,然后对所有用户试一试。攻击者一定会发现一些钥匙。(我假设您使用攻击者可以看到的用户记录存储每个用户的随机盐,或者您拥有攻击者能够通过妥协获得的秘密盐。)
https://stackoverflow.com/questions/7238624
复制相似问题