使用哈希键在客户端验证验证码安全吗?

Is it safe to validate a captcha on the clientside with its hashkey?

我经常使用验证码来保护表单。到目前为止,出于显而易见的原因,我只在服务器端检查用户输入的验证码解决方案。

对于所有其他表单字段,我在客户端上进行了 javascript 验证,因为这样更快、更人性化; (当然我在服务器端做了二次检查),但是对于验证码字段,我只是检查它是否已填写。

我的问题: 使用验证码的哈希键(例如 MD5)进行客户端 JavaScript 验证是否安全?使用散列键不会将验证码本身泄露给机器人,应该很安全,对吧?

但也许我对这个想法完全错了...... 感谢您的见解!

听起来可行,但是您绝对应该考虑使用长随机盐来防止基于预先计算的简单攻击。

更正式地说,您必须发送图像、长随机盐和哈希值。然后,在客户端,您将计算与盐连接的输入文本的哈希值,并将结果与​​哈希值进行比较。

由于较长的随机盐值,攻击者预先计算的集合必须非常大才能反映所有可能的盐值。

此外,忘记 MD5,因为它被认为是不安全的。使用更强的哈希函数。

另请注意,这只会是可能 增强 用户体验的东西(如果输入错误的验证码,则无需 POST 页面)但绝对是你不能只能在客户端。实际验证必须在服务器端完成。

我想说的是足够安全,但这可能有助于 OCR 机器人检查它们是否正确,而无需在服务器上碰碰运气并冒着丢失当前验证码的风险(因为如果答案不正确,服务器会使代码无效)已提供,不会给您第二次机会使用相同的验证码重试)。

假设 OCR 机器人无法判断验证码的最后一个字母是小写字母 L 还是数字“1”?在没有客户端验证的传统验证码中,机器人只是试试运气,如果它猜错了,服务器会记录失败并重新发送一个完全不同的验证码,因此 OCR 必须重新开始。

现在想象一下上面的场景,但是有了客户端验证,这里的机器人有一种方法可以在不通知服务器的情况下验证他们是否有正确的答案,所以在这种情况下,如果机器人不确定,它尝试针对哈希的所有可能性,只提交正确的答案。基本上,这使机器人能够在不告诉服务器的情况下犯错误,而不必重新开始。

最后,我脑子里没有精确的数字,但即使每次使用不同的盐,根据可能性的数量(比如 4 个字母数字字符,不区分大小写),也有可能暴力破解每一个在合理的时间内甚至不进行 OCR 的可能性。为了缓解这种情况,您应该使用哈希的多次迭代,这样在计算上就很难尝试所有可能的答案。