在我的网络应用程序的一种形式上,我有一个隐藏的字段,我需要防止因安全原因而被篡改。我试图想出一个解决方案,我可以检测隐藏字段的值是否已经改变,并做出适当反应(即通用“出错了,请再试一次”错误信息)。解决方案应该足够安全,暴力攻击是不可行的。我有一个基本的解决方案,我觉得它会起作用,但我不是安全专家,我可能在这里完全遗漏了一些东西。
我的想法是渲染两个隐藏的输入:一个名为“important_value”,包含我需要保护的值,一个名为“important_value_hash”,包含与常量长随机字符串连接的重要值的SHA哈希(即每次都会使用相同的字符串)。提交表单时,服务器将重新计算SHA哈希值,并与提交的important_value_hash值进行比较。如果它们不相同,则important_value已被篡改。
我还可以使用SHA的输入字符串(可能是用户的IP地址?)连接其他值,但我不知道这是否真的让我获得了任何东西。
这会安全吗?任何人都可以了解它是如何被打破的,以及可以/应该做些什么来改进它?
谢谢!
答案 0 :(得分:4)
最好将哈希值存储在服务器端。 可以想象,攻击者可以更改值并生成他/她自己的SHA-1哈希并添加随机字符串(他们可以很容易地反复访问该页面)。如果哈希是在服务器端(可能在某种缓存中),您可以重新计算哈希并检查它以确保该值没有以任何方式被篡改。
修改强>
我读了关于随机字符串(恒定盐)的错误问题。但我想最初的观点仍然存在。攻击者可以建立一个与隐藏值对应的哈希值列表。
答案 1 :(得分:1)
数字签名
它可能有点矫枉过正,但这与您对外发电子邮件进行数字签名时没有什么不同,因此收件人可以验证其来源和内容是否真实。篡改敏感字段的签名可以通过您的防篡改字段释放到野外,几乎不用担心检测不到篡改,只要您保护私钥并验证数据和签名与公众返回时的关键。
这个方案甚至有一个漂亮的属性,你可以限制“签名”到受保护的服务器/进程集合访问私钥,但使用一组更大的服务器/进程与公钥一起提供处理表单提交
如果你有一个非常敏感的“do-not-tamper”字段并且无法在服务器上维护它的散列签名,那么这就是我要考虑的方法。
虽然我怀疑大多数人都熟悉数字签名,但对于任何一个不熟悉的人来说,这里都有一些维基百科:
Public Key Cryptography - Security
......另一种类型的应用程序 公钥加密是的 数字签名方案。数字 签名方案可用于 发件人认证和 不可抵赖性。在这样的方案中 想要发送消息的用户 计算这个的数字签名 消息,然后发送此数字 签名和消息一起 预期的接收者。数字 签名方案有财产 签名只能计算 了解私钥。 验证消息是否已经过 由用户签名但尚未签名 修改接收器只需要 知道相应的公钥。在 存在某些情况(例如RSA) 数字签名方案有很多 与加密方案的相似之处。在 其他情况(例如DSA)算法 不像任何加密 方案。 ...
答案 2 :(得分:1)
如果您无法在服务器上处理会话,请考虑使用您的私钥加密数据并为其生成HMAC,将结果作为隐藏字段发送。然后,您可以验证返回的内容是否与发送的内容相匹配,因为没有其他人知道您的私钥,否则其他任何人都无法生成有效信息。但是处理服务器端的“不得更改”数据会好得多。
您必须认识到,任何有足够决心的人都可以向您(您的表单)发送包含他们想要的信息的HTTP请求,这些信息可能与您上次发送的信息有任何关系。
答案 3 :(得分:0)
如果您不能/不会存储哈希服务器端,则需要能够在服务器端重新生成它以进行验证。
为了它的价值,你也应该为你的哈希加盐。当你说:
时,这可能就是你的意思与常数长连接 随机字符串(即相同的字符串 将每次都使用)
知道如果每个用户/登录/ sesison的值不相同,那么它实际上不是盐值。
答案 4 :(得分:0)
只要你用你的生命保护“恒定的长随机字符串”,那么你的方法相对较强。
为了更进一步,您可以生成一次/唯一的“常量长随机字符串”。
答案 5 :(得分:0)
您所描述的内容类似于所谓的金丝雀所需的部分实施,并用于缓解跨站点请求伪造攻击。
一般来说,HTML表单中的隐藏输入包含使用HTTP请求回发的加密值。会话中保存的浏览器cookie或字符串包含相同的加密值,这样当隐藏的输入值被解密并且cookie /会话值被解密时,未加密的值将相互比较 - 如果它们不相同,则为HTTP请求不可信任。
加密值可能是包含属性的对象。例如,在ASP.NET MVC中,canary实现使用一个类,该类包含经过身份验证的用户名的属性,使用RNGCryptoServiceProvider
类生成的加密伪随机值,创建对象的DateTime(UTC格式)和一个可选的盐串。然后使用带有256位密钥的AES加密算法对对象进行加密,并在请求进入时使用相同的密钥解密。