互联网安全架构平台设计之防止抓包篡改数据
一、抓包是什么?
抓包(packet capture)就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全,抓包也经常被用来进行数据截取等。
抓包工具是拦截查看网络数据包内容的软件,通过对抓获的数据包进行分析,可以得到有用的信息。
二、什么是抓包工具?
抓包工具一般是用来做网络数据分析的,浏览器F12就是最常用的抓包工具,但是抓包工具到了黑客的手中就变成了用来做破坏的常用手段。假设你手机连接了一个免费WiFi,但是如果路由器被黑客控制后就可以通过抓包工具来获取你手机浏览信息以及一些个人信息,甚至借用你的个人账户信息对一些浏览的不健全的网站做数据篡改。
如下截图:获取了我电脑网络访问的所有地址,如果是路由器就可以获取所有连接该路由器的机器所访问的信息,很多公司都有监控员工电脑浏览网址的软件就是根据这个原理制作出来的。
一般作为开发人员,应该知道后端代码如何调试,用PostMan输入Cookie信息,然后就可以随意模拟请求发送到后台了,所以非法份子获取到你的个人账户信息和cookie信息后,对于一些不健全的网站就可以模拟请求利用账户的信息来修改其中的数据。
抓包工具就可以针对抓取的用户请求来篡改数据,抓取到请求后可以在请求前和请求后修改数据,例如针对针对某购物请求做了拦截,用户请求是买2件商品,当发出请求后修改为买10件,然后对请求传回的response修改为正常的,用户界面永远是对的,但是实际上的请求的数据被篡改了。再来个常见的例子,游戏外挂,就是针对某款游戏做的抓包篡改数据,然后你就编程了无敌一刀999伤害了,然后把针对这个游戏所有的请求做了分析修改写成一个脚本,外挂就出来了
三、如何防止抓包篡改数据
- 设置客户端IP黑/白名单
针对某些特殊的服务只允许特定机器访问的时候就限制只有这几个IP可以访问就行了。 - 使用Https
Https与Http的区别就是Https是安全的,因为Https在Http的基础上做了加密及认证,已经包含了签名功能。 - 验证签名
这是最常用的方法,签名是一个参数,根据本次请求的数据生成的一个独特的参数(例如:name=张三&value=123&sign=abc6yui5,sign就是签名,根据name和value的值通过特定算法生成的独特的字符串),服务器端获取请求后再计算一次签名做对比,只有当签名一致的时候才会验证通过。
//这是网上随便截取的一段SignUtils核心代码
public static String signTopRequest(Map<String, String> params, String secret, String signMethod) throws IOException {
// 第一步:首先对请求的参数进行排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起形成个字符串
StringBuilder query = new StringBuilder();
if (SIGN_METHOD_MD5.equals(signMethod)) {
query.append(secret);
}
for (String key : keys) {
String value = params.get(key);
if (StringUtils.areNotEmpty(key, value)) {
query.append(key).append(value);
}
}
// 第三步:使用MD5/HMAC加密
byte[] bytes;
if (SIGN_METHOD_HMAC.equals(signMethod)) {
bytes = encryptHMAC(query.toString(), secret);
} else {
query.append(secret);
bytes = encryptMD5(query.toString());
}
// 第四步:把二进制转化为大写的十六进制(正确签名应该为32大写字符串,此方法需要时使用)
return byte2hex(bytes);
}
然后写个验证签名的拦截器,当然此处需要注意的地方,可能有XSSFilter存在导致请求数据已经是修改过的了,因为过滤器执行优先于拦截器。
public class SignHandler implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Map parameterMap = request.getParameterMap();
String md5Sign = SignUtil.signTopRequest(parameterMap, "123456", "md5");
String sign = request.getParameter("sign");
if(md5Sign.equals(sign)){
//验证成功
return true;
}else{
System.out.println("验证失败,请求数据被篡改");
return false;
}
}
}
MD5加密是网站常用的加密手段,是不可逆的,一般用来做网站用户密码的加密,一般都不会直接使用MD5,而是加了盐,因为直接使用MD5可以被暴力破解的,网上的MD5解密就是有一堆MD5数据库,针对数据做MD5匹配就能分析出来加密手段了。用MD5加盐是必须的,而且盐值最好做成动态的,例如使用id+字符串作为盐值安全性就更高了,注意不要用一些可变字段作为盐值,用用户名做盐值然后用户改名密码就上不去了。
内容来源: 蚂蚁课堂