自建加密解密传输&kaptcha验证码使用次数限制思路

序:
      刚来第一天环境刚搞好,svn刚装完,账号都还没有,员工手册还没有学习完,就被要求开始撸代码。还好同事之间沟通狠顺畅,直接可以找到人问东西。
     今天主要比较紧急的待修复项:
     1.验证码只能使用一次的问题
     2.登录/修改密码过程中数据传输简单的decode不满足安全性要求
     首先说下这边的验证码是怎么生成的。一般我们已说到验证码只能用一次想到的肯定是利用redis存储生成的验证码,设置时效性。但是这里生成验证码用的是一个组件kaptcha,这个组件的核心思路就是生成了验证码放session里,没有设置有效时长这个说法。此外异步校验也是每次从session取比对,代码如下:
   String  captchaCode = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        if(captchaCode.equalsIgnoreCase(verificationCode)){
            return "true";
        }
     如果比对一致就表示校验通过。这里权限是使用shiro,登陆也校验验证码,这时候是从token里取比对。重点来了,我处理这里保证验证码只能使用一次也是在这里做的逻辑,也就是在shiro的继承AuthorizingRealm里的doGetAuthenticationInfo方法里做文章,思路:就是在校验token里的验证码比对时从session删除验证码,这样再次传这个验证码就过不了了,具体逻辑:
String captcha = (String) SecurityUtils
                .getSubject()
                .getSession()
                .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);

//删除session里的验证码        
SecurityUtils.getSubject().getSession().removeAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        if(StringUtils.isBlank(captcha)) {
            throw new IncorrectCaptchaException("验证码失效");
        }
//比对token里与session里的验证码
        if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha()) ){
            throw new IncorrectCaptchaException("验证码错误");
        }
另外做以上操作,注意需要配合页面的刷新做,比如页面提示验证失效或错误了需要重新获取ajax生成(保证新生成一个放session里备用)
     接下来该说第二个问题,那就是加密传输的问题。
     其实这里的思路受起来也狠简单,就是传统的加密配合自己写的加密使用。自己写的加密的思路:
     每个输入的字符生成一个的字符串,而这个字符串里某位是角标,真正的charAt(角标)位置才是输入内容,其他位则是随机生成,这个角标也是随机的,所以生成的串每次看起来不一样,这样抓到的包看到的就是每次发送的都不一样,让黑客难以分析出规律。前台自建加密js:
function randomsort(d, c) {
    return Math.random() > 0.5 ? -1 : 1
}
function encryption(e) {
    var g = e.split("");
    for (var f = 0; f < g.length; f++) {
        var h = Math.floor(Math.random() * 3) + 1;
        var c = (f + 1) + "0" + (h + 1);
        for (var d = 0; d < h; d++) {
            c += Math.floor(Math.random() * 9)
        }
        g[f] = c + g[f];
        var b = 9 - g[f].length;
        if (b > 2) {
            for (d = 0; d < b; d++) {
                g[f] += Math.floor(Math.random() * 9)
            }
        }
    }
    g.sort(randomsort);
    var a = "";
    for (f = 0; f < g.length; f++) {
        a += g[f] + "$"
    }
    return a
};
页面使用也超级简单:
var username = encode(encryption($("#username").val()));   
$("#sendUsername").val(username);
var password = encode(encryption($("#password").val()));
$("#sendPassword").val(password);
其实就是获取用户输入的明文进行自建加密,然后再调用一次其他常规加密,这里的encode就是其他的常规加密。
这样因为自建加密生成的串随机,那么常规加密生成的就每次不一样,尽管真正的每次用户名密码都一样。
但是说实话,别人要是花店心思先获取这个自建加密js(浏览器打开debug就可以看到,不过这个js要想让用户看到但是不知道什么意思除了变量定义用abcd外还可以加混淆,这样真的绝大部分黑客就望而止步了),说远了。
再来说说后台的解密,其实根据这个js已经可以知道java的解密怎么写了,这里贴出的我故意留个bug吧,可以用,但是会有问题,不能告诉大家见谅,如果真需要知道,可以单独找我。
public static String decryp(String str){
        String[] strs = str.split("[$]");
        Map<Integer, String> map = new TreeMap<Integer, String>(
                new Comparator<Integer>() {
                    public int compare(Integer obj1, Integer obj2) {
                        return obj2.compareTo(obj1);
                    }
         });
        for(String temp : strs){
            Integer number = Integer.parseInt(temp.substring(0, temp.indexOf("0")));
            temp = temp.substring(temp.indexOf("0") + 1, temp.length());
            Integer index = Integer.parseInt(temp.substring(0, 1));
            String[] temps = temp.split("");
            String value = temps[index];
            map.put(number, value);
        }
        Set<Integer> keySet = map.keySet();
        Iterator<Integer> iter = keySet.iterator();
        String result = "";
        while (iter.hasNext()) {
            Integer key = iter.next();
            result = map.get(key) + result;
        }
        return result;
    }
这是自建加密的后台解密,常规加密的解密就不说了。
到此私密数据的安全传输就提高一个档次了,加个混淆安全性就更上一层楼了。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥仔哥哥1930

来一波支持,吃不了亏上不了当

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值