如果目标是防止“静态”URL被篡改,那么可以简单地加密参数或对其进行签名。在URL参数后面添加MD5哈希值以及一些盐(salt)可能已经足够安全了。盐可以是会话中存储的随机字符串。
然后可以这样做:
http://example.com/service?x=123&y=Bob&sig=ABCD1324
这种技术暴露了数据(即他们可以“看到”xyz=123),但他们无法更改数据。
“加密”有一个优点(我使用这个术语并不严格)。这是指加密URL的整个参数部分。
在这里,你可以做一些像这样的事情:
http://example.com/service?data=ABC1235ABC
使用加密的好处有两个。
首先,它可以保护数据(例如,用户永远看不到xyz=123)。
另一个特点是它是可扩展的:
http://example.com/service?data=ABC1235ABC&newparm=123&otherparm=abc
在这里,您可以解码原始负载,并与新数据进行(安全)合并。
因此,请求可以向请求添加数据,但不能更改现有数据。
您可以通过签名技术执行相同的操作,只需将整个请求合并为一个“blob”,该“blob”会被隐式签名。那是“有效”的加密,只是一种弱加密。
显然,您不希望在客户端上执行任何此操作。毫无意义。如果您可以做到这一点,“他们”也可以做到这一点,您无法区分它们,因此最好根本不要这样做 - 除非您想在普通HTTP端口(而不是TLS)上“加密”数据,但是然后人们会明智地想知道“为什么要麻烦”。
对于Java,所有这些工作都在过滤器中完成,这是我做的方式。后端与此隔离开来。
如果您愿意,可以使用出站过滤器使后端完全与此隔离,以处理URL加密/签名。
这也是我所做的。
缺点是要正确和高效地完成这项工作非常复杂。您需要一个轻量级的HTML解析器来提取URL(我编写了一个流解析器来即时完成它,因此它没有将整个页面复制到RAM中)。
好处是所有内容侧“只需工作”,因为它们对此一无所知。
在处理Javascript时还有一些特殊处理(因为您的过滤器不容易“知道”何时存在要加密的URL)。我通过要求签名的URL是具体的“var signedURL ='....'”来解决这个问题,因此我可以轻松找到输出中的那些。对于设计师来说,并不像您想象的那样具有压倒性的负担。
过滤器的另一个好处是您可以将其禁用。如果出现一些“奇怪的行为”,只需关闭它即可。如果行为继续,您已经发现了与加密相关的错误。它还使开发人员可以使用纯文本进行工作,并将加密留给集成测试。
虽然需要付出努力,但最终效果很好。