我正在编写一个应用程序,主要目的是保留用户购买的列表。

我想确保即使我作为开发人员(或任何具有完全访问数据库的人)也无法弄清楚某人花了多少钱或他购买了多少钱。

我最初提出了以下方案:

    --------------+------------+-----------
    user_hash     | item       | price
    --------------+------------+-----------
    a45cd654fe810 | Strip club |     400.00
    a45cd654fe810 | Ferrari    | 1510800.00
    54da2241211c2 | Beer       |       5.00
    54da2241211c2 | iPhone     |     399.00
  • 用户使用用户名和密码登录。
  • 从密码计算 user_hash (可能有盐等)。
  • 使用Hash访问使用普通SQL-Queries的用户数据。

鉴于足够的用户,几乎不可能通过仅知道他的名字来判断特定用户花费了多少钱。

这是一件明智的事情,还是我完全愚蠢?

有帮助吗?

解决方案

问题是,如果某人已经完全访问了数据库,那么将记录链接到特定人才只是时间问题。在数据库(或应用程序本身)中的某个地方,您必须建立用户与项目之间的关系。如果有人有完全访问权限,那么他们将可以访问该机制。

绝对无法防止这种情况。

现实情况是,通过完全访问,我们处于信任的位置。这意味着公司经理必须相信,即使您可以看到数据,您也不会以任何方式采取行动。这是像道德这样的小事情发挥作用的地方。

就是说,现在,许多公司将开发和生产人员分开。目的是从与LIVE(IE:真实)数据直接接触中删除开发。这具有许多优势,安全性和数据可靠性位于堆的顶部。

唯一真正的缺点是 一些 开发人员认为,如果没有生产访问,他们就无法解决问题。但是,这根本不是真的。

然后,生产人员将是唯一可以访问直播服务器的人。他们通常会接受更大程度的审查(犯罪历史和其他背景调查),与您必须保护的数据类型相当。

这一切的目的是这是一个人事问题。而且不是一个可以通过技术手段真正解决的方法。


更新

这里的其他人似乎缺少一个非常重要且至关重要的难题。也就是说,由于某种原因,数据正在进入系统中。这个原因几乎是普遍的,以便可以共享。在收费报告的情况下,该数据已输入,以便会计可以知道要偿还谁。

这意味着该系统在某种程度上必须匹配没有数据输入人员(即:销售人员)的用户和项目。

而且,由于必须将这些数据捆绑在一起,而无需在此涉及的所有方面键入安全代码以“发布”数据,因此DBA绝对能够查看查询日志以找出谁是谁。而且,无论您想投入多少哈希标记,我都可以很容易地添加。 Triple des也不会拯救您。

归根结底,您所做的只是使开发更加艰难,绝对为零。我不能足够强调这一点:隐藏数据中的数据的唯一方法是对1. 只要 进入它或2的人可以访问。

关于选项1,如果唯一可以访问它的人就是输入它的人。.好吧,它在公司数据库中没有意义。

其他提示

恐怕您的应用程序可以将人链接到其数据,任何开发人员/管理员都可以。

您唯一可以做的就是使链接更难降低开发人员/管理员,但是如果您更难将用户链接到数据,那么您的服务器也会更加困难。


基于@no的想法的想法:

您可以将经典的用户/密码登录到您的应用程序(Hashed密码或其他任何内容),以及用于确保数据安全的特殊“通行证”。此“通行证”不会存储在您的数据库中。

当您的客户端登录您的应用程序时,我必须提供用户/密码/通过。使用数据库检查用户/密码,通行证将用于加载/写入数据。

当您需要编写数据时,您会制作“用户名/通行证”夫妇的哈希,并将其存储为将客户端链接到数据的密钥。

当您需要加载数据时,您会制作“用户名/通行证”夫妇的哈希,并加载与此哈希相匹配的每个数据。

这样一来,您的数据和用户之间就不可能建立链接。

另一方面,(正如我在对@no的评论中所说的那样) 当心碰撞. 。另外,如果您的用户写不良的“通行证”,则无法检查。


更新:在最后一部分中,我有了另一个想法,您可以存储在数据库中“通过/密码”夫妇的哈希,这样您就可以检查您的“通行证”是否还可以。

  1. 使用以下方式创建一个用户表
    1. USER_ID:身份列(自动生成ID)
    2. 用户名
    3. 密码:确保它是哈希!
  2. 在您的示例中创建一个产品表:
    1. USER_HASH
    2. 物品
    3. 价格

USER_HASH将基于永不更改的User_ID。用户名和密码可以根据需要免费更改。当用户登录时,您将比较用户名/密码以获取user_id。您可以在会话期间将User_hash发送回客户端,或将HASH的加密/间接版本(可能是Session ID),服务器将user_hash存储在会话中)。

现在,您需要一种将USER_ID放置到user_hash中并保持保护的方法。

  1. 如果您按照@NO建议进行客户端,则客户端需要使用user_id。大型安全漏洞(尤其是如果它是网络应用程序),可以轻松地篡改哈希,并且算法可向公众免费提供。
  2. 您可以将其作为数据库中的函数。坏主意,因为数据库具有链接记录的所有片段。
  3. 对于网站或客户端/服务器应用程序,您可以在服务器端代码上使用它。好多了,但是一位开发人员可以访问哈希算法和数据。
  4. 让另一个开发人员编写哈希算法(您无权访问)并将其粘在另一台服务器上(您也无法访问)作为TCP/Web服务。然后,您的服务器端代码将传递用户ID并返回哈希。您将没有算法,但是您可以将所有用户ID发送给所有用户ID以获取所有散布。尽管该服务可能有记录,但要尝试最大程度地降低风险。
  5. 如果仅仅是客户端数据库应用程序,则只有选择#1和2。我强烈建议添加另一个是服务器端的[业务]层,与数据库服务器分开。

编辑:这重叠了以前的一些点。有3个服务器:

  • 身份验证服务器: :员工A可以访问。维护用户表。具有使用用户/密码组合的Web服务(带有加密通信)。哈希密码,在表中查找user_id,生成user_hash。这样,您不能简单地发送所有user_ids并恢复哈希。您必须拥有未存储在任何地方的密码,并且仅在身份验证过程中可用。
  • 主数据库服务器: :员工B可以访问。仅存储user_hash。没有用户,没有密码。您可以使用user_hash链接数据,但是实际的用户信息在其他地方。
  • 网站服务器: :员工B可以访问。获取登录信息,传递到身份验证服务器,返回哈希,然后处理登录信息。将HASH在会话中进行写入/查询数据库。

因此,员工A具有user_id,用户名,密码和算法。员工B具有user_hash和数据。除非员工B修改网站以存储原始的用户/密码,否则他无法链接到真实用户。

使用SQL分析,员工A将获得user_id,用户名和密码哈希(因为以后在代码中生成了用户_hash)。员工B将获得user_hash和数据。

确保数据不能连接到其属于的人的唯一方法是不首先记录身份信息(使所有内容都匿名)。但是,这样做很可能会使您的应用程序毫无意义。您可以使这更难做到,但是您不能使它变得不可能。

在单独的数据库中存储用户数据并识别信息(可能是在单独的服务器上),并将两者与ID号链接起来可能是您可以做的最接近的事情。这样,您已经尽可能地隔离了两个数据集。您仍然必须将ID号保留为它们之间的链接;否则,您将无法检索用户的数据。

此外,我不建议将哈希密码用作唯一标识符。当用户更改密码时,您将不得不浏览并更新所有数据库,以将旧的哈希密码ID替换为新的密码ID。通常,使用不基于任何用户信息的唯一ID(以帮助确保它将保持静态)要容易得多。

这最终是一个社会问题,而不是技术问题。最好的解决方案将是一个社会解决方案。在硬化系统以防止未经授权的访问(黑客等)之后,您可能会获得更好的里程,以与用户建立信任并实施有关数据安全的政策和程序系统。包括滥用客户信息的员工的具体处罚。由于单一违反客户信任的行为足以破坏您的声誉并将所有用户驱逐出境,因此使用“顶级”访问的人滥用这些数据的诱惑少于您想象的(因为公司的崩溃通常超过任何收益)。

请记住,即使在不实际存储该人的识别信息的任何地方,仅将足够的信息与相同的密钥相关联,您也可以使您能够找出与某些信息相关的人的身份。仅仅一个简单的例子,您可以打电话给脱衣舞俱乐部,询问哪个客户驾驶法拉利。

因此,当您识别医疗记录(用于研究等)时,您必须为89岁以上的人删除生日(因为老年人很少见,以至于特定的生日可以指向一个人)并删除任何指定少于20,000人的区域的地理编码。 (看 http://privacy.miami.edu/glossary/xd_deidentied_health_info.htm)

AOL在发布搜索数据时发现了一个艰难的方法,可以通过知道与匿名人士相关的搜索可以识别人们。 (看 http://www.fi.muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf)

看来您对此有好处,但是您只是在思考(或者我根本不理解)

编写一个基于输入的新字符串的函数(这将是其用户名或其他无法更改加班的东西)

构建用户哈希时,将返回的字符串用作盐(再次,我将使用用户ID或用户名作为哈希构建器的输入,因为它们不会像用户的密码或电子邮件一样更改)

将所有用户操作与用户哈希相关联。

没有人只有数据库访问可以确定用户哈希的含义。即使尝试通过尝试不同的种子来强迫野蛮的尝试,盐组合最终也将毫无用处,因为盐被确定为用户名的变体。

我认为您在最初的帖子中回答了自己的问题。

实际上,有一种方法可以做您在说的事情...

您可以将用户键入他的名称和密码为一个纯粹的客户端脚本的表格,该脚本根据名称和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 更改,每次散布一个字符串时,都会得到不同的东西。

  • 使用普通哈希算法哈希用户名+密码。这将与数据库中的“秘密”表的键相同,但是数据库中的其他内容都不匹配。
  • 将Hashed通行证附加到用户名,并使用上述算法进行哈希。
  • 基本16编码 var n 并在原始哈希中附加具有定界器字符。

这将创建一个 独特的哈希 (每次都会有所不同)可以通过系统对数据库中的每一列进行检查。可以设置该系统仅允许一次特定的独特哈希(例如每年一次),防止MITM攻击,并且用户的信息都没有通过电线传递。除非我错过了什么,否则对此没有任何不安全。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top