我需要一个函数,给定一个salt整数和一个值整数将返回一个小的哈希字符串。使用1和56调用该函数可能会返回“1AF3”。用2和56调用它可能会返回“C2FA”。
背景资料: 我有一个Web应用程序(如果重要的话用C#编写),它将员工Id值存储为整数。用户需要能够看到该Id的一致表示,但是没有用户应该看到实际的Id,或者该ID的表示与另一个用户看到的相同。
例如,假设有一个ID为56的员工。
当用户1登录时,无论他在哪里看到该员工,他都会看到“1AF3”或其他内容。他可能会在应用程序的不同页面上看到此员工,其ID应始终为1AF3,因此他知道这是同一个人。
当用户2登录时,如果他遇到同一个员工,他总会看到“C2FA”或其他东西。用户2也是如此:无论他在系统中的哪个位置,他都会看到一个员工用相同的字符串表示。
如果用户1在用户1登录时查看用户1的肩膀,则用户2应该无法识别用户1屏幕上的任何员工,因为此哈希应该是不可逆转的。
这有意义吗?
另外一个要求是,由于用户将通过电子邮件,电话和传真讨论这些员工,因此散列需要具有最小尺寸且不包含非字母数字字符。 10个字符或更少是理想的。
也许有一种方法可以将SHA-256结果“折叠”为更少的字符,因为可以使用整个字母表?我不知道。
更新:另一个演练 谢谢大家给出了一个机会,但似乎我在解释它或其他事情做得不好。
让我们假装你和我都是这个系统的用户。你是弗雷德,我是克里斯。您的UserId为2,我的UserId为1.我们还假设系统中有5名员工。员工不是用户。您可以将它们视为产品,或任何您想要的产品。我只是在谈论你,弗雷德和我,克里斯各自处理的5个通用实体。
弗雷德,每次登录时,您都需要能够唯一地识别每个员工。每次我,克里斯,登录,我也需要与员工合作,我也需要能够独特地识别他们。但是,当你管理员工时,我是否应该瞧不起你,我不应该弄清楚你在管理哪些人。因此,在数据库中,员工ID分别为1,2,3,4和5.您和我在我们的界面中看不到它们。我可能会看到A,B,C,D和E,你可能会看到F,G,H,I和J.所以当E和J都代表同一个员工时,我不能看你的屏幕而你正在与您的员工“J”合作,并且知道您正在与员工5合作,因为对我而言,该员工对我而言称为员工“E”。
因此,弗雷德和克里斯可以与同一组员工一起工作,但如果他们看到彼此的工作或电子邮件中的讨论,他们将无法知道其他人正在谈论的员工。
我以为我可以通过获取真实的员工ID并使用用户ID作为盐来对其进行哈希来实现这种“与用户相关的实时EmployeeID”。
由于弗雷德和克里斯都需要通过电子邮件和电话与客户和客户讨论员工,我希望他们在这些讨论中使用的ID尽可能简单。
答案 0 :(得分:3)
从概念上讲,这就是你想要的:
您有一组员工ID,您可以将其表示为给定空间 S 中的元素。您还有一些用户,并且您希望每个用户都能看到特定于用户的空间 S 的排列,并且任何其他用户都无法猜到该排列的详细信息。 / p>
这需要对称加密。即,每个雇员ID是数值(例如,32位整数),用户'A'将雇员 x 视为 E k (x) , k 是一个特定于'A'的密钥,'B'无法猜测。所以你需要两件事:
对于分组密码,问题在于短分块是正常使用分组密码的安全问题(即加密长消息)。因此,所有已发布的安全块密码都使用大块(64位或更多)。通过使用大写和小写字母,64位可以表示超过11个字符,并且数字(62 11 稍微大于2 64 )。如果这对您来说足够好,那么请使用3DES。如果你想要更小的东西,你将不得不设计自己的密码,根本不推荐。您可能想尝试KeeLoq:请参阅this paper以获取指针(KeeLoq在加密方面“已损坏”但不过多,根据您的上下文)。在给定可搜索流密码的情况下,对于具有任意块大小的构建块密码存在generic method,但这主要是理论上的(实现需要蹒跚通过高精度浮点值,这可以完成但非常慢)。
对于特定于用户的密钥:您需要Web应用程序可以计算的内容,而不是用户。这意味着Web应用程序知道密钥 K ;然后,用户特定的加密密钥可以是HMAC(具有良好的散列函数,例如SHA-256)应用于用户ID,并使用密钥 K 的结果。然后,将HMAC输出截断为用户特定密钥所需的长度(例如,3DES需要24字节密钥)。
C#具有TripleDES和HMAC / SHA-256实现(在System.Security.Cryptography
命名空间中)。
(对于具有32位块的分组密码,没有普遍接受的安全标准。这仍然是一个开放的研究领域。)
答案 1 :(得分:1)
这种方法可能存在问题,但您可以这样做:
index = octet % array_size
。索引给出了每个符号的位置同样,我对密码学,哈希函数等几乎没有经验,所以你可能想要用这种方法。
答案 2 :(得分:0)
有很多方法可以“去匿名化”信息。如果您可以更具体地了解背景以及您真正想要保护的“资产”,那将有所帮助。见我们的常见问题
例如,一个用户可能知道另一个用户的号码吗?如果他们通过其他方式发现1AF3和C2FA之间的对应关系,他们可能会很快发现它。
但是特别针对你较窄的问题,一个好的哈希已经很好地混合了,所以我认为你可以截断,例如,一个SHA-256哈希值。但托马斯可能会知道那里的确定答案。
答案 3 :(得分:0)
以下是我的想法(我想如果你说出了你的问题,我会说出我的答案。我猜你会觉得有帮助):
您提供的是员工ID和员工替代ID。既然它们必须是可逆的而不是公众的,那么你需要将它存储在一个双向配对中并保密。由于存在与散列冲突的风险,并且您无论如何都必须有反向映射,因此备用ID也可能是随机字符串。无论如何,ID应该是任意的,我真的想知道你的方法对于一个员工有两个id的安全益处;它让我想起了“不可能的任务”和NOC名单。
答案 4 :(得分:0)
根据您添加的额外信息,提出一种方法。这个想法的安全性非常非常轻,如果你认为人们会试图破解它,我不会推荐它,但它值得扔进锅里。
您可以根据自己的员工ID对员工ID进行位移来创建个人哈希。然后通过向结果数字添加所需的额外混淆代码,例如将其转换为十六进制。 E.g。
string hashedEmployeeId = (employeeIdToHash << myEmployeeId).ToString("X");
这将根据您自己的ID生成哈希的员工ID,但是当员工ID变大时(尤其是您自己的ID),您可能会遇到问题。
重申一下,这本身并不是非常安全,但它可能对你有所帮助。
答案 5 :(得分:0)
使用4个字符,您将总共拥有:36 ^ 4 = 1679616。 你可以置换所有雇员的可能性。 如果你计算de square root,你得到1296。
然后,您可以生成一个包含第一列中所有可能性的有序表,然后将ID从1到1296随机分配到oder列。你会得到这样的东西:
key a b
AAAA 386 67
AAAB 86 945
...
使用此解决方案,您将拥有一个可扩展至最多1296名员工的查找表。但是,如果你考虑在你的键上添加一个额外的字符,你将获得更多的可能性(36 ^ 5)^ 0.5 = 7776。
通过这个解决方案,一把钥匙可以让你有机会在1296或7776看到有关雇员的信息。
可能是性能问题,但我叮叮当你可以使用缓存管理它,或者甚至可以将所有数据加载到内存中并使用一种树形图来找到两个给定ID的相应密钥。