我有一个项目需要在美国社会安全号码(格式为ddd-dd-dddd
)的前端进行验证。一个建议是使用哈希算法,但考虑到使用的微小字符集([0-9]
),这将是灾难性的。以某种高概率验证数字是否正确并允许后端进行最终==
检查是可以接受的,但我需要做得比“有九位数”等好得多。
在我寻找更好的替代方案时,我找到了ISBN个数字和UPC的验证校验和。这些看起来像是一个很好的选择,在前端有很高的成功率。
鉴于这些限制,我有三个问题:
一如既往地谢谢 乔
更新:
回答下面的问题,更多细节。我有先前输入的客户SSN,安全地存储在应用程序的后端。我需要做的是验证(在最大程度上)客户在此页面上再次输入相同的值。问题是,如果某些未经授权的人能够访问该页面,我需要防止信息被偶然泄露给前端。
这就是为什么MD5 / SHA1哈希是不合适的:即它可以用来导出完整的SSN而没有太大困难。校验和(例如,模11)几乎不向前端提供信息,同时仍允许现场验证的高度准确性。但是,如上所述,我对它的普遍适用性感到担忧。
答案 0 :(得分:3)
维基百科不是这种事情的最佳来源,但考虑到这一点,http://en.wikipedia.org/wiki/Social_Security_number说
与许多类似的数字不同,不包括校验位。
但在此之前,它提到了一些广泛使用的过滤器:
SSA发布用于每个区号的最后一个组号。由于组号以常规(如果不常见)模式分配,因此可以识别包含无效组号的未发布SSN。尽管采取了这些措施,但仅使用公开可用的信息不能轻易地检测到许多欺诈性SSN。为此,有许多在线服务提供SSN验证。
答案 1 :(得分:2)
重申基本要求:
我可能会建议使用加密(SHA-1等),但不将完整的哈希值发送给客户端。例如,仅发送160位散列结果的最低4位[1]。通过发送4位校验和,您检测数据输入错误的几率为15/16--这意味着您将在93%的时间内检测到错误。不过,另一方面是你已经“泄露”足够的信息以将其SSN降低到1/16的搜索空间。由您决定客户端验证的便利性是否值得泄漏。
通过调整发送的“校验和”位数,您可以在方便用户(即检测错误)和信息泄漏之间进行调整。
最后,根据您的要求,我怀疑这种便利性/泄漏权衡是一个固有的问题:当然,您可以使用更复杂的加密质询/响应算法(正如Nick ODell精明地建议的那样)。但是,这样做需要单独的往返请求 - 你说你首先想要避免的事情。
[1]在一个好的加密散列函数中,由于雪崩效应,所有输出数字都很好地随机化,所以你选择的具体数字并不特别重要 - 它们都是有效随机的。
答案 2 :(得分:2)
简单的解决方案。将数字mod 100001作为校验和。有1/100_000的机会你不小心用错误的数字得到校验和(并且它会抵消一两个数字的错误取消),以及10,000个可能的SSN,因此你没有透露SSN对攻击者。
唯一的缺点是10,000个可能的其他SSN很容易弄明白。如果这个人可以从其他地方获得最后4个SSN,那么他们可能会找出SSN。如果您担心这一点,那么您应该获取用户的SSN号码,添加一个盐并哈希。并故意使用昂贵的哈希算法来做到这一点。 (您可以迭代一个更便宜的算法,如MD5,固定次数以增加成本。)然后只使用一定数量的位。这里的重点是,虽然有人可以通过十亿可能的SSN来提出有限的可能性列表,但这样做会花费更多。希望他们不要打扰。