我正在编写一个应用程序,其主要目的是保留用户列表 购买。
我想确保即使我作为开发人员(或任何有完整的人) 访问数据库)无法计算出多少钱 特定的人已经花了或者他买了什么。
我最初想出了以下方案:
--------------+------------+----------- user_hash | item | price --------------+------------+----------- a45cd654fe810 | Strip club | 400.00 a45cd654fe810 | Ferrari | 1510800.00 54da2241211c2 | Beer | 5.00 54da2241211c2 | iPhone | 399.00
user_hash
(可能还有盐腌等)。如果有足够的用户,几乎不可能知道多少 一个特定用户通过知道他的名字而花费的钱。
这是一件明智的事吗,还是我完全愚蠢?
答案 0 :(得分:4)
我担心,如果您的应用程序可以将某个人与其数据相关联,那么任何开发人员/管理员都可以。
你唯一能做的就是让链接变得更难,减慢开发人员/管理员的速度,但是如果你把用户与数据联系起来更加困难,那么你的服务器也会变得更难。
基于@no想法的想法:
您可以使用经典的用户/密码登录您的应用程序(哈希密码或其他),以及用于保证数据安全的特殊“通行证”。此“通行证”不会存储在您的数据库中。
当您的客户登录您的应用程序时,我必须提供用户/密码/通行证。使用数据库检查用户/密码,该传递将用于加载/写入数据。
当您需要编写数据时,您可以对“用户名/密码”对进行哈希处理,并将其存储为将客户端与数据相关联的密钥。
当您需要加载数据时,您可以对“username / pass”对进行哈希处理,并加载与此哈希匹配的每个数据。
这样就无法在您的数据和用户之间建立链接。
另一方面,(正如我在对@no的评论中所说)小心碰撞。此外,如果您的用户写了一个错误的“通行证”,您将无法检查它。
更新:对于最后一部分,我有另一个想法,你可以在你的数据库中存储你的“通行证/密码”夫妇的哈希值,这样你就可以检查你的“通行证”是否合适。
答案 1 :(得分:2)
user_hash将基于永远不会更改的user_id。用户名和密码可根据需要随意更改。当用户登录时,您将比较用户名/密码以获取user_id。您可以在会话期间将user_hash发送回客户端,或者加密/间接版本的哈希(可以是会话ID,服务器将user_hash存储在会话中)。
现在您需要一种方法将user_id哈希到user_hash并保护它。
修改强> 这与以前的一些要点重叠。有3台服务器:
因此,员工A具有user_id,用户名,密码和算法。员工B具有user_hash和数据。除非员工B修改网站以存储原始用户/密码,否则他无法链接到真实用户。
使用SQL分析,Employee A将获得user_id,用户名和密码哈希(因为user_hash稍后在代码中生成)。员工B将获得user_hash和数据。
答案 2 :(得分:1)
确保数据无法连接到其所属人员的唯一方法是不首先记录身份信息(使所有内容都匿名)。但是,这样做很可能会使您的应用毫无意义。你可以让这更难做,但你不能让它变得不可能。
将用户数据和识别信息存储在单独的数据库中(可能在不同的服务器上),并将两者与ID号相关联,这可能是您可以做的最接近的事情。这样,您已尽可能隔离了两个数据集。您仍然必须保留该ID号作为它们之间的链接;否则,您将无法检索用户的数据。
此外,我不建议使用散列密码作为唯一标识符。当用户更改其密码时,您必须通过并更新所有数据库,以使用新的密码ID替换旧的哈希密码ID。使用不基于任何用户信息的唯一ID通常要容易得多(以帮助确保它保持静态)。
这最终成为一个社会问题,而不是技术问题。最好的解决方案将是社交解决方案。在强化系统以防止未经授权的访问(黑客等)之后,您可能会获得更好的里程,与您的用户建立信任并实施有关数据安全的策略和程序系统。对滥用客户信息的员工包含特定处罚。由于单一的客户信任破坏足以破坏您的声誉并驱使您的所有用户离开,因此具有“顶级”访问权限的人滥用此数据的诱惑比您想象的要少(因为公司通常会崩溃)超过任何收益)。
答案 3 :(得分:1)
请记住,即使没有将人的识别信息实际存储在任何地方,仅仅将足够的信息与相同的密钥相关联,也可以让您找出与某些信息相关联的人的身份。举个简单的例子,你可以打电话给脱衣舞俱乐部,询问哪个顾客驾驶法拉利。
出于这个原因,当您取消识别医疗记录(用于研究等)时,您必须删除89岁以上人群的生日(因为那些老年人很少,特定的出生日期可能指向单个人)并删除任何指定包含少于20,000人的区域的地理编码。 (见http://privacy.med.miami.edu/glossary/xd_deidentified_health_info.htm)
AOL在发布搜索数据时发现了一种艰难的方式,只需了解与匿名人士相关的搜索内容即可识别人员。 (见http://www.fi.muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf)
答案 4 :(得分:0)
问题是如果有人已经拥有对数据库的完全访问权限,那么将记录链接到特定人员只是时间问题。在数据库的某个位置(或应用程序本身),您必须在用户和项目之间建立关系。如果有人具有完全访问权限,那么他们将可以访问该机制。
绝对没有办法阻止这种情况。
现实情况是,通过完全访问,我们处于信任的位置。这意味着公司经理必须相信即使您可以看到数据,也不会以任何方式对其进行操作。这就是道德这样的小事情发挥作用的地方。
现在,据说,许多公司将开发和生产人员分开。目的是将开发与直播(即:真实)数据直接联系。这具有许多优点,安全性和数据可靠性处于最重要的位置。
唯一真正的缺点是某些开发人员认为他们无法在没有生产访问权限的情况下解决问题。然而,事实并非如此。
然后,生产人员将是唯一可以访问实时服务器的人员。他们通常会接受更大程度的审查(犯罪记录和其他背景调查),这与您必须保护的数据类型相关。
所有这一切的重点在于这是一个人事问题;而不是一个可以用技术手段真正解决的问题。
<强>更新强>
其他人似乎错过了一个非常重要且非常重要的难题。即,由于某种原因数据正被输入系统。这个原因几乎普遍存在,因此可以共享。在费用报告的情况下,输入该数据,以便会计可以知道谁应该回报。
这意味着系统在某种程度上必须匹配用户和项目,而不会登录数据录入人员(即:销售人员)。
因为这些数据必须捆绑在一起而没有所有相关方站在那里输入安全代码来“释放”数据,然后DBA绝对能够查看查询日志以确定谁是谁。无论你想要投入多少哈希标记,我都可以轻松添加。三重DES也不会拯救你。
在一天结束时,您所做的就是让开发变得更加困难,绝对没有安全保障。我不能强调这一点:从dba中隐藏数据的唯一方法是1.要使输入它的人能够访问 的数据,或者2.存在于第一位。
关于选项1,如果唯一可以访问它的人是输入它的人......那么,它就没有必要在公司数据库中。
答案 5 :(得分:0)
实际上,有一种方法可以做你正在谈论的事情......
您可以让用户在运行纯客户端脚本的表单中键入他的名称和密码,该脚本根据名称和pw生成哈希。该哈希用作用户的唯一ID,并发送到服务器。这样,服务器只通过哈希而不是名称来了解用户。
为了使其工作,散列必须与普通密码散列不同,并且用户需要在服务器具有任何“内存”之前额外输入其名称/密码。有人买了。
服务器可以记住该人在会话期间购买的内容然后“忘记”,因为数据库中不包含用户帐户和敏感信息之间的链接。
修改强>
回应那些说客户端散列是安全风险的人:如果你做得对,那就不是了。应该假设哈希算法是已知的或可知的。否则说是“通过默默无闻的安全”。散列不涉及任何私钥,动态散列可用于防止篡改。
例如,你采用这样的哈希生成器:
http://baagoe.com/en/RandomMusings/javascript/Mash.js
// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagoe <baagoe@baagoe.com>, 2010
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
mash.version = 'Mash 0.9';
return mash;
}
了解n
如何更改,每次散列字符串时都会得到不同的内容。
var n
并将其附加到带有分隔符的原始哈希中。这将创建一个唯一哈希(每次都不同),系统可以根据数据库中的每一列进行检查。系统可以设置为仅允许一次特定的唯一哈希(例如,每年一次),防止MITM攻击,并且没有用户的信息通过网络传递。除非我遗漏了什么,否则没有什么不安全感。
答案 6 :(得分:0)
看起来你正好跟着这个,但你只是在思考它(或者我根本就不理解它)
根据输入编写一个构建新字符串的函数(这将是他们的用户名或其他不能随时改变的东西)
在构建用户哈希时使用返回的字符串作为salt(同样我会使用userID或username作为哈希构建器的输入,因为它们不会像用户的密码或电子邮件那样更改)
将所有用户操作与用户哈希相关联。
没有只有数据库访问权限的人可以确定用户哈希到底是什么意思。即使尝试通过尝试不同的种子,盐组合强制它也会最终无用,因为盐被确定为用户名的变体。
我认为您已经在初次发帖时回答了自己的问题。