图片验证码是验证码的一种,图片验证码常见的形式有输入图片中字母、数字等,目前的发展更为多元。下面小编从多方面跟大家讲讲图片验证码。
全自动区分计算机和人类的图灵测试(Completely Automated Public Turing test to tell Computers and HumansApart,简称CAPTCHA),俗称验证码,是一种区分用户是计算机或人的全自动化程序。
标准验证码即是我们常见的图形验证码、语音验证码,基于机器难以处理复杂的计算机视觉及语音识别问题,而人类却可以轻松的识别来区分人类及机器。
创新验证码是基于第一代验证码的核心思想(通过人类知识可以解答,而计算机难以解答的问题进行人机判断)而产生的创新的交互优化型验证码。第二代验证码基于第一代验证码的核心原理:“人机之间知识的差异”,拓展出大量创新型验证码。
无知识型验证码最大的特点是不再基于知识进行人机判断,而是基于人类固有的生物特征以及操作的环境信息综合决策,来判断是人类还是机器。如Google的ReCaptcha。
(1)避免触发验证码验证码的引入会带来用户友好度的下降,增加验证码输入以及人眼对验证码识别的可能错误等都会带来不好的使用体验。这对追求用户体验的网站来说,在没遇到可疑行为时,其采取的策略是默认不开启验证码功能,当触发可疑行为识别规则时,才会出现验证码。基于此原理,对攻击方来说,就是尽量避免触发可能出现验证码的规则。一般可疑行为识别是通过检查频繁尝试并且出错这个行为来进行,基于此的对抗措施则是使用不同的IP来进行尝试,或者等待足够的时间再次尝试,这样让目标网站程序认为这些尝试都是正常的访问请求,从而在自动化程序端连续作业时不会出现验证码而达到绕过的目的。
(2)验证码固定从前面的验证码固定问题描述可看出,攻击者可以在同一个会话下,在获得第一个验证码后,后面不再主动触发验证码生成页面,并且一直使用第一个验证码就可循环进行后面的表单操作,从而绕过了验证码的屏障作用。
(3)验证码机器自动识别计算机自动识别验证码,主要原理是通过一定的算法预先建立验证码范围内的字体特征库,再将要识别的验证码通过同样的算法生成特征,与之前保存的特征库进行比较,进而得到图片验证码的值。一般地,其识别过程有如下图所示的处理流程:
(4)深度学习——GANs网络网站登录图像验证码的发展到现在,遇到的最大的威胁可能就是深度学习了,特别是GANs网络的出现,让图像验证码遇到了最强劲的对手。
图片验证码在不断发展,目的就是为了避免一些非正常用户操作。而不论图形验证码如何发展,终究是敌不过攻击者的破解手段,正所谓 “道高一尺魔高一丈” 。就比如铁路12306的图片点选验证码,不仅没有挡住黄牛,反而让黄牛抢票更加轻松。
在开发者与攻击者的角逐中,受影响最大的莫过于我们用户了。各种千奇百怪的复杂验证码,不是为了考验黑客,而是考验用户。
验证码的图片常常扭曲得连人眼都认不出来。这在那些无实义的字词中体现得格外明显,就像“rl10Ozirl”。里面用的到底是小写的字母“L”还是数字“1”?是数字“0”还是字母“O”?真正的用户在使用途中真的是饱经磨难。。。“为什么受伤的总是我”。
据卡内基梅隆大学的研发小组估算,全球人口每天在这些烦人的屏障入口处所耗费的时间,累计可达15 w小时。有种新型的验证码——“多重验证码”(reCaptcha),至少是把这些时间用在了公共价值的创造上。你看到的图片是一个从扫描不良的谷歌(微博)图书中截取出来的模糊单词;而你输入该词拼写的过程,其实就是在协助谷歌处理、识别一段有效文本。
即便如此,我们这些守规矩的用户,每天还是会浪费掉17年的时间。这简直是对生命的可耻浪费。而用户真正想要的是去掉这些额外的操作。
风控防火墙是近几年研发出来的一种专门应用于原图片验证场景的替代品。它将完全取缔原来的图片验证码,将用户体验做到最好。在用户完全无感的情况下来区分正常用户与非正常用户。通过AI立体防御机制,实时防控。用户再也不用担心出现(“验证码输入错误!
”)的烦人提示了。
进入 防火墙控制台,在左侧导航栏选择【网站管理】,进入网站管理页面,单击【发到邮箱】接收密钥。
前往新昕科技官网,在顶部导航栏选择【解决方案】>【下载中心】,进入下载中心页面,找到短信防火墙服务器安装包,点击【下载链接】即可下载。
Java 在页面合适的位置(标签内)加入以下代码引入JS文件:
<script type="text/javascript" src="/NxtJsServlet"></script>
PHP 在页面合适的位置(标签内)加入以下代码引入JS文件:
<script id="finger" type="text/javascript" src="/nxt_inc/nxt_front.php"></script>
Java
修改配置(和业务系统同系统不需要修改):
newxtc.ini (存放位置:"/WEB-INF/classes/newxtc.ini")
修改参数(fireWareUrl)–> fireWareUrl=http://localhost:7502
public RetMsg smsSend(HttpServletRequest request, HttpServletResponse response, String clientMobile) {
RetMsg retMsg = new RetMsg(-1, "系统异常");
FwClient fwClient = new FwClientImpl();
try {
// 1 调用【短信防火墙】短信发送请求
HashMap < String, Object > paramMap = fwClient.getSendReq(request, clientMobile);
String jsonReq = fwClient.execReq(paramMap);
String smsSendRet = fwClient.getRetVaule(jsonReq, "riskResult");
if("REJECT".equals(smsSendRet)) {
retMsg.setRet(3);
retMsg.setMsg("请求过于频繁");
}
else {
// 业务 TODO
// 业务调用短信接口 TODO
// 调用短信接口 结束
if(smsRetMsg != null && smsRetMsg.getRet() == 0) {
// 2 调用【短信防火墙】成功结果
fwClient.execSucc(paramMap);
logger.debug("send succ");
retMsg.setRet(0);
retMsg.setMsg("发送验证码成功");
}
else {
// 2 调用【短信防火墙】失败结果
SmsVerifyCache.getInstance().remove(clientMobile);
fwClient.execFail(paramMap);
retMsg.setRet(-1);
retMsg.setMsg("发送验证码失败");
}
}
}
catch(Exception e) {
for(StackTraceElement elment: e.getStackTrace()) {
logger.error(elment.toString());
}
}
return retMsg;
}
public RetMsg smsVerify(HttpServletRequest request, HttpServletResponse response, String clientMobile, String smsVerifyCode) {
FwClient fwClient = new FwClientImpl();
RetMsg retMsg = new RetMsg(-1, "系统异常");
if(smsVerifyCode == null || smsVerifyCode.isEmpty()) {
retMsg.setRet(1);
retMsg.setMsg("输入验证码为空");
}
else {
// 1 调用【短信防火墙】验证请求
HashMap < String, Object > paramMap = fwClient.getVerifyReq(request, clientMobile); // 请求防火墙
String jsonReq = fwClient.execReq(paramMap);
// 报文处理
String smsSendRet = fwClient.getRetVaule(jsonReq, "riskResult");
if("REJECT".equals(smsSendRet)) {
retMsg.setRet(3);
retMsg.setMsg("请求过于频繁");
}
// 业务 TODO
if(cacheSmsVerify != null && cacheSmsVerify.getVerifyCode() != null && !cacheSmsVerify.getVerifyCode().isEmpty()) {
if(cacheSmsVerify.getVerifyCode().equals(smsVerifyCode)) {
retMsg.setRet(0);
retMsg.setMsg("验证成功");
}
else {
retMsg.setRet(1);
retMsg.setMsg("验证码错误");
}
}
else {
retMsg.setRet(-9);
retMsg.setMsg("验证码超时");
}
if(retMsg.getRet() == 0) {
// 2 调用【短信防火墙】成功结果
fwClient.execSucc(paramMap);
}
else {
// 2 调用【短信防火墙】失败结果
fwClient.execFail(paramMap);
}
}
return retMsg;
}
PHP
修改配置文件(和业务系统同系统不需要修改):
nxt_ini.php (存放位置:"\nxt_inc") 修改参数($GLOBALS
[“fireWareUrl”])–>$GLOBALS[“fireWareUrl”]=“http://localhost:7502”
require_once $_SERVER['DOCUMENT_ROOT'].
"/nxt_inc/nxt_client.php";
/**
* 发送短信
* @param $mobile
*/
public
function send(string $mobile) {
$fwClient = new ClientApi();
// 获取下发短信报文
$paramMap = $fwClient - > getSendReq($phone);
// 执行下发短信请求
$jsonReq = $fwClient - > execReq($paramMap);
$fwRet = $fwClient - > getRetVaule($jsonReq, "riskResult");
if("REJECT" != $fwRet) {
// 发送短信业务 TODO
if(发送成功标记) {
// 下发短信成功
$fwClient - > execSucc($paramMap);
}
else {
// 下发短信失败
$fwClient - > execFail($paramMap);
}
}
}
/**
* 短信验证
* @param $mobile
*/
public
function smsVerify(string $mobile) {
$fwClient = new ClientApi();
// 获取短信验证报文
$paramMap = $fwClient - > getVerifyReq($phone);
// 执行短信验证请求
$jsonReq = $fwClient - > execReq($paramMap);
$fwRet = $fwClient - > getRetVaule($jsonReq, "riskResult");
if("REJECT" != $fwRet) {
// 验证短信业务 TODO
if(验证成功标记) {
// 验证短信成功
$fwClient - > execSucc($paramMap);
}
else {
// 验证短信失败
$fwClient - > execFail($paramMap);
}
}
}
防御拦截数据尽收眼底,实时查看当日数据详情与近期风险趋势。 通过风控数据看板,可查看1-30天的验证情况、风控拦截情况以及验证事件触发的AI模型情况。
进入防火墙控制台,在左侧导航栏选择【风险大盘】,进入风险大盘页面。
这篇文章到这里就结束了,感谢大佬们驻足观看,大佬们点个关注、点个赞呗~
谢谢大佬~
作者:香芋味的猫丶