博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于3des加密解密URL
阅读量:5824 次
发布时间:2019-06-18

本文共 4541 字,大约阅读时间需要 15 分钟。

hot3.png

在构建restful架构服务或简单的查询时,往往会遇到参数明文的问题。

例如: xxxx.jsp?id=3

这种常见的URL有个潜在的苦逼之处就是,别人可以轻易做个爬虫把你的从id=1~N的数据爬走。你忙半天过几天就发现有个站和你一样……

解决方法之一是加密url,把id=3变成诸如id=qweoqwuiqlqjeu11312ljlqow之类的玩意

网上搜刮来的一个类,略微修改以便实用。

import java.io.UnsupportedEncodingException;import java.text.SimpleDateFormat;import java.util.Date;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class DESede {       //算法DESede    private static final String Algorithm = "DESede";       //工作模式CBC(ECB),填充模式PKCS5Padding(NoPadding)    //eg: DESede/CBC/PKCS5Padding, DESede/ECB/PKCS5Padding    private static final String Transformation = "DESede/CBC/PKCS5Padding";       //向量iv,ECB不需要向量iv,CBC需要向量iv    //CBC工作模式下,同样的密钥,同样的明文,使用不同的向量iv加密 会生成不同的密文    private static final String Iv = "\0\0\0\0\0\0\0\0";    public String encryptMode(byte[] keybyte, byte[] src) {        try {            // 根据给定的字节数组和算法构造一个密钥            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);            // 加密            IvParameterSpec iv = new IvParameterSpec(Iv.getBytes());            Cipher c1 = Cipher.getInstance(Transformation);            c1.init(Cipher.ENCRYPT_MODE, deskey, iv);            return byte2hex(c1.doFinal(src));        } catch (java.security.NoSuchAlgorithmException e1) {            e1.printStackTrace();        } catch (javax.crypto.NoSuchPaddingException e2) {            e2.printStackTrace();        } catch (java.lang.Exception e3) {            e3.printStackTrace();        }        return null;    }       public String byte2hex(byte[] b) { // 一个字节的数,        // 转成16进制字符串        String hs = "";        String stmp = "";        for (int n = 0; n < b.length; n++) {            // 整数转成十六进制表示            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));            if (stmp.length() == 1)                hs = hs + "0" + stmp;            else                hs = hs + stmp;        }        return hs; // 转成大写    }             public String encode(String src,String key)throws UnsupportedEncodingException {     //加密过的        String encryptData = encryptMode(key, src);     return encryptData;    }       public String decode(String src,String key)throws UnsupportedEncodingException {      //解密过的        String decryptData = decryptMode( getKeyByte(key), hex2byte(src.getBytes()));     return decryptData;    }       public String encryptMode(String key, String src) throws UnsupportedEncodingException {        return encryptMode(getKeyByte(key), src.getBytes());    }       public byte[] getKeyByte(String key) throws UnsupportedEncodingException {        // 加密数据必须是24位,不足补0;超出24位则只取前面的24数据        byte[] data = key.getBytes();        int len = data.length;        byte[] newdata = new byte[24];        System.arraycopy(data, 0, newdata, 0, len > 24 ? 24 : len);        return newdata;    }           public String decryptMode(byte[] keybyte, byte[] src) {        try {            // 生成密钥            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);            // 解密            IvParameterSpec iv = new IvParameterSpec(Iv.getBytes());            Cipher c1 = Cipher.getInstance(Transformation);            c1.init(Cipher.DECRYPT_MODE, deskey, iv);            byte[] data = c1.doFinal(src);            return new String(data);        } catch (java.security.NoSuchAlgorithmException e1) {            e1.printStackTrace();        } catch (javax.crypto.NoSuchPaddingException e2) {            e2.printStackTrace();        } catch (java.lang.Exception e3) {            e3.printStackTrace();        }        return null;    }       public byte[] hex2byte(byte[] b) {        if ((b.length % 2) != 0)            throw new IllegalArgumentException("长度不是偶数");        byte[] b2 = new byte[b.length / 2];        for (int n = 0; n < b.length; n += 2) {            String item = new String(b, n, 2);            // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个进制字节            b2[n / 2] = (byte) Integer.parseInt(item, 16);        }        return b2;    }}

网上能找到不少代码,然而其中一部分的问题在于编码和转换是巨坑。这个很好,直接能用。

应用时,

编码就调用encode,把id=xx的xx, encode(xx,key1)得到个乱码字符串n。只有decode(n,key1)才能解开

public class xxxx{   private String key1="aaaa123231313";   private String key2="qweqeweqweqw";    ……
public void function 解码URL获取真正参数值并处理(…String n…){     //n是id=n,那串乱码     DESede ss = new DESede();     updateKey(); //可以把key1,key2等根据日期和预设字符混淆生成下新的     String number=ss.decode(n,key1);     //检查number是否有效格式,如果是null就请来访者吃error,有效就照常查数据库     ……   }   }

很简单的,但是很实用。

我不会告诉你爬虫搞得服务器日志增长巨快有多恶心。

 

转载于:https://my.oschina.net/meikaiyuan/blog/470630

你可能感兴趣的文章
RHEL6.5安装成功ORACLE11GR2之后,编写PROC程序出错解决方法
查看>>
(50)与magento集成
查看>>
Ubuntu设置python3为默认版本
查看>>
JsonCpp 的使用
查看>>
问题账户需求分析
查看>>
JavaSE-代码块
查看>>
爬取所有校园新闻
查看>>
32、SpringBoot-整合Dubbo
查看>>
python面向对象基础
查看>>
HDU 2044 一只小蜜蜂(递归)
查看>>
docker 下 安装rancher 笔记
查看>>
spring两大核心对象IOC和AOP(新手理解)
查看>>
数据分析相关
查看>>
Python LDAP中的时间戳转换为Linux下时间
查看>>
微信小程序蓝牙连接小票打印机
查看>>
环境错误2
查看>>
C++_了解虚函数的概念
查看>>
全新jmeter视频已经上架
查看>>
Windows 8下如何删除无线配置文件
查看>>
解决Windows 7中文件关联和打开方式
查看>>