5

我想建立一个无法追踪的投票系统,该系统将允许注册用户以某种方式对某些敏感问题进行投票,这将使得在数据库受损的情况下(包括被过度好奇的数据库“妥协”)无法追踪用户的投票行政)。

详细设置:

  1. 每个用户都已注册,没有完全匿名的投票。
  2. Sockpuppets、假账户等不在此问题的范围内——这是注册系统的责任。
  3. 每个注册用户只能投一票(可能是任何东西:简单的是/否或重量或其他)。
  4. 用户必须能够更改/删除他的投票,直到投票结束。
  5. 没有必要让用户查看自己的投票,但可以通过与删除/更改相同的方式来完成。
  6. 即使有人可以访问用户身份验证数据库和投票数据库,他们也不能将每个投票跟踪回用户(从某种意义上说,暴力破解或以其他方式破解整个用户帐户的访问权限并不容易)。
  7. 系统除了通讯以外的所有部分都是开放的,所以不能有隐藏的钥匙。中间人攻击不在问题范围内,但攻击者可以完全访问源、身份验证和投票数据库。
  8. 用户很懒惰。他们不需要任何其他投票专用密钥或密码。系统不得要求用户在本地提供或保留任何内容,除了他们已经用于登录的常用登录名/密码/密钥。
  9. 篡改投票和除程序<->数据库通信和不可追踪性之外的任何安全问题都是更广泛的问题,因此也超出了这个问题的范围。

我有一些解决方案,我会在宽限期后发布我自己的答案。

4

4 回答 4

2

假设 DB Admin 无权访问将具有投票系统的应用程序代码,并假设 DB Admin 查看投票不是问题(只是将投票链接到一个人)

在您存储用户投票的表中,创建一个额外的列,该列将包含来自投票的用户的一些信息的加盐哈希(姓名、用户名、电子邮件、b-day、这些的组合)。这是重要的事情,数据库管理员不应该知道存储在数据库中的用户唯一值是如何首先生成然后加密的。

只需假设您想出的用户令牌(姓名、电子邮件)是密码,并且您想在不知道实际密码是什么的情况下将其存储在数据库中。更多信息可以在这里找到 在数据库中存储密码的最佳方式

因此,使用您的每用户哈希/加盐算法,每次用户想要投/编辑或删除他们的投票时,您可以先生成哈希,然后尝试在投票表中找到具有该哈希值的记录,并对其采取行动因此。(如果不存在则插入,如果存在则更新,如果用户需要则删除)

一旦投票过程关闭,您甚至可以丢弃该投票过程的答案的哈希值,这样就无法将投票链接到用户

于 2012-06-05T10:44:42.203 回答
1

要求用户在投票/更改他们的不可追踪投票时提供密码,并执行与存储用户身份验证信息(盐+单向哈希)两次相同的操作:一次使用您存储的盐使用散列密码,并再次使用您为这对特定的{user, poll}. 设置或更改投票的请求应包含以下部分:

  • 用户名
  • 身份验证盐 #1 的密码哈希 #1
  • 投票特定盐 #2 的密码哈希 #2
  • 投票本身

您使用用户名和哈希 #1 来验证您是否从已知用户那里获得投票,然后将哈希 #2 与投票本身一起存储在用户投票表中。hash #2 和 salt #2 的值用于唯一标识投票。

由于密码哈希是单向的,只有知道纯文本密码的人才能产生哈希 #2。当 salt #1 与 salt #2 不同时,即使拥有这两个数据库的人也无法与投票的用户建立连接。

于 2012-06-05T14:22:13.767 回答
0

如果您只想对具有 DB 访问权限的人隐藏它,请使用存储在 DB 外部的密钥的对称加密。

否则,您将需要为所有用户分配一个秘密,并将该秘密与投票而不是用户 ID 一起存储。秘密应该以某种方式由服务器签名,但不以任何方式连接到用户。用户稍后可以使用秘密更改他的投票,并且您可以验证投票,因为它们已签名,但是无法将它们与用户联系起来(除非攻击者有办法观察秘密中的分配过程)。

如果你不想用额外的秘密给用户带来不便,你需要使用他们已经拥有的唯一一个:他们的密码。您可以使用从用户名、密码和随机盐创建的哈希来索引投票。这本质上是不安全的,因为许多密码很容易被猜到;严格的密码策略和非常慢的散列算法(例如 bcrpyt)有所帮助。例如。如果您将 bcrypt 工作因子设置为需要几秒钟来计算哈希,这对于您的服务器来说仍然是可以接受的,但攻击者不太可能获得超过几百万次尝试破坏哈希,这可能还不够即使是字典攻击。

于 2012-06-05T10:42:20.173 回答
0

你想要的似乎是不可能的,因为条件相互排斥。

要么设置好密钥,要么危及安全。

于 2012-06-05T10:54:15.787 回答