基于工作量证明的防暴力破解

什么是工作量证明

工作量证明(Proof Of Work,简称POW),简单理解就是一份证明,用来确认你做过一定量的工作。

工作量证明系统(或者说协议、函数),是一种应对拒绝服务攻击和其他服务滥用的经济对策。它要求发起者进行一定量的运算,也就意味着需要消耗计算机一定的时间。

工作量证明的基本原理

工作量证明系统主要特征是客户端需要做一定难度的工作得出一个结果,验证方却很容易通过结果来检查出客户端是不是做了相应的工作。这种方案的一个核心特征是不对称性:工作对于请求方是适中的,对于验证方则是易于验证的。它与验证码不同,验证码的设计出发点是易于被人类解决而不易被计算机解决。

举个例子,这个例子就是区块链中常用的POW工作算法的基本原理:
给定的一个基本的字符串"Hello, world!",我们给出的工作量要求是,可以在这个字符串后面添加一个叫做nonce的整数值,对变更后(添加nonce)的字符串进行SHA256哈希运算,如果得到的哈希结果(以16进制的形式表示)是以"0000"开头的,则验证通过。为了达到这个工作量证明的目标。我们需要不停的递增nonce值,对得到的新字符串进行SHA256哈希运算,直到得到满足条件的nonce值。按照这个规则,我们需要经过4251次计算才能找到恰好前4位为0的哈希散列。

"Hello, world!4248" => 6e110d98b388e77e9c6f042ac6b497cec46660deef75a55ebc7cfdf65cc0b965
"Hello, world!4249" => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6
"Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

在这个例子中,4251次SHA256哈希计算,就是我们要求的“工作量”,当然,这个工作量不是固定的,和难度值有关(难度也就是要求的“0000”开头的“0”的个数,0的个数越多,难度越大);我们可以根据业务情况设置一个合理的难度;

验证方拿到字符串"Hello, world!"及提交的nonce值后,只要进行一次SHA256运算,就可以验证是否通过(如果得到的哈希结果是以"0000"开头的,则验证通过),难度是不是低多了。

暴力破解及常见防止办法

黑客常用暴力破解的办法还破解帐号口令,利用工具,向验证方提交不同的密码进行验证,它每秒种可以发起成千上万次的偿试,直到试出真实口令;

现有的防止办法有:
验证码:目前各种形式的验证码较多,验证码的设计出发点是易于被人类解决而不易被计算机解决;
限制提交次数:限制同一IP或对同一帐号提交验证的错误次数;

工作量证明可能不是最好的办法,但也给大家提供了一种新的解题思路了。而且相比验证码方式,省去了用户输入验证码的要求,是不是更人性化? :-)

基于工作量证明的防暴力破解

如果我们要求用户登录时,除提交帐号,口令外,还需要提供一个工作量证明,也就是上面例子中的nonce值,就可以大大限制黑客每秒能够提交的请求数;

假设没有工作量证明之前,黑客每秒可以至少提交 1000次验证请求;
需要提交工作量证明之后,每个请求的工作量假设平均需要一台普通电脑4秒的计算量,那黑客最快每4秒才能发起一次请求,破解难度增加了约4000倍;但4秒的计算量,对于正常用户的请求,是可以接受的.

当然有人可能会说,那整个大型机来计算,可能每次只要0.001秒就算出来了。。但是,你得先有台大型机吧。。。。。这难度不是一般人搞得定的。。。。还有这样做值不值呢。。。。

案例实现

下面我就一个网站的登录验证,看看具体怎么通过工作量证明来防止暴力破解:

网页表单,要求用户提供用户名,密码,同时设置一个隐藏变量,用于保存工作量证明的nonce值。

<form action="/user/login" id="loginForm">
	<input type="hidden" id="nonce" name="nonce" />
	账号:<input type="text" id="username" name="username">
	密码:<input type="password" id="passwd" name="passwd">
	<button type="button" onclick="login();">登录</button>
</form>

下面准备工作计算相关代码,先从网上下载支持SHA256算法的JS库,我这直接引入第三方提供的资源:

<script src="https://cdn.bootcss.com/jshashes/1.0.7/hashes.min.js"></script>

下面是获取工作量证明JS函数:

//根据输入数据进行SHA256运算,找出匹配条件的nonce值
function getNonce(data) {
       var hash;
  	   var nonce = 0;
       var sha256 = new Hashes.SHA256();

       while(nonce < 100000000) {
         hash = sha256.hex(data+nonce);    	      
         if (hash<"00005") {		//这个是工作量难度,与验证方保持一致即可
           break;
         } else {
            nonce ++;
         }
       }
       return nonce;
  }

登录之前,先进行工作量运算,获取到工作量证明nonce再提交:

function login() {
	var username = $("#username").val();
	var passwd = $("#passwd").val();
	
	//获取工作量证明,计算时间 0-8秒左右
	var nonce=getNonce(username+hashPasswd);
	$("#nonce").val(nonce);
	
    $("#loginForm").submit();
	}

最后,服务端先进行工作量验证,再进行帐号口令验证:

 boolean login( String username,String passwd,String nonce) {
 .......
 
if (!validateNonce( form.getUsername(), form.getHashPasswd(),nonce)) { //工作量验证未通过
	return false;
 }
  .......
//  验证帐号口令
ReturnObjectStatus<User> ros=userService.login(username,passwd);
 .......
}

//工作量验证,返回true通过验证
private boolean validateNonce(String username,String passwd,String nonce) {
    	String data=username+passwd+nonce;
    	String hash=SHA256.getSHA256(data);
        if (hash.compareTo("00005")>0) {
    		return false;
    	}
    	return true;
 }

这样就完成了从用户浏览器中用JS完成工作量证明nonce的计算,并提交服务端验证的全过程。。。

基于工作量证明的扩展应用

按照以上思路,工作量证明还可以应用于其它场景,比如防止黄牛抢票,防止发送垃圾邮件等。
更多应用场景留给大家发挥啦。。。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值