润乾报表单独部署url安全之加解密

润乾报表与用户的系统集成,一般有两种方案。一是集成到用户系统中。二是将润乾单独部署到一个应用下。

两种方案各有利弊:第一种方案对于安全性等方面可以统一管理,但是报表本身如果数据量大并发大造成的压力会直接影响用户自己的系统。第二种方案在报表服务器承受压力过大数据量过大的时候,不会影响到用户本身的系统,也就是说就算报表服务器压力饱和进入等待状态,用户的系统也可以正常的使用,众所周知润乾报表的调用一般直接通过url的方式进行调用,那么第二种方案中的url就无法被用户系统所控制,造成了一定的安全隐患。

 

下面就介绍几种解决此类问题的方案之中的一种:对url进行加解密

 

案例场景:

通过用户系统访问一张报表时,当然会带着一些用户信息或是其他参数传递过来。如果这时这个url的明文被其他人记住,比如url拼参数username=zhangsan,这时李四记住了这个url并且与自己访问该资源的url进行对比发现传入参数为用户姓名拼音,由于采用的是第二种方案,用户系统并不能控制,这样就可以肆无忌惮的去查看其他人的信息,导致信息的泄漏。

 

解决思路:

这时我们可以采取对url中的明文进行加解密的操作,通过用户系统传递参数之前进行加密,然后传递到报表服务器端,在jsp中或者报表中进行解密。(下文介绍是在报表中解密)

 

实现方法:

一、首先确定加解密规则,这里使用的是AES加解密方法,密钥为16位英文,由于是说明将密钥定义死在相应类中。

二、通过测试类将username=zhangsan加密为:

880CB3013AB0D0F3A91B1C36B323F6E40294D3BE6EEFAA38135690CA3DCC61A2模拟用户系统传递参数到报表服务器的url为:

http://127.0.0.1:6001/demo/reportJsp/showReport.jsp?aes=880CB3013AB0D0F3A91B1C36B323F6E40294D3BE6EEFAA38135690CA3DCC61A2&raq=demo.raq

三、编写AES加解密的自定义函数,接受参数时只用到解密函数,加密函数是在报表中超链接等位置再次使用时可以调用加密函数。

1、实现AES加解密的类

public class AES {  

      

    private static final String AES = "AES";  

 

    private static final String CRYPT_KEY = "aaaaaaaaaaaaaaaa";  

 

    /** 

     * 加密 

     *  

     * @param encryptStr 

     * @return 

     */ 

    public static byte[] encrypt(byte[] src, String key) throws Exception {  

        Cipher cipher = Cipher.getInstance(AES);  

        SecretKeySpec securekey = new SecretKeySpec(key.getBytes(), AES);  

        cipher.init(Cipher.ENCRYPT_MODE, securekey);//设置密钥和加密形式  

        return cipher.doFinal(src);  

    }  

 

    /** 

     * 解密 

     *  

     * @param decryptStr 

     * @return 

     * @throws Exception 

     */ 

    public static byte[] decrypt(byte[] src, String key)  throws Exception  {  

        Cipher cipher = Cipher.getInstance(AES);  

        SecretKeySpec securekey = new SecretKeySpec(key.getBytes(), AES);//设置加密Key  

        cipher.init(Cipher.DECRYPT_MODE, securekey);//设置密钥和解密形式  

        return cipher.doFinal(src);  

    }  

      

    /** 

     * 二行制转十六进制字符串 

     *  

     * @param b 

     * @return 

     */ 

    public static String byte2hex(byte[] b) {  

        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.toUpperCase();  

    }  

 

    public static 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);  

            b2[n / 2] = (byte) Integer.parseInt(item, 16);  

        }  

        return b2;  

    }  

      

    /** 

     * 解密 

     *  

     * @param data 

     * @return 

     * @throws Exception 

     */ 

    public final static String decrypt(String data) {  

        try {  

            return new String(decrypt(hex2byte(data.getBytes()),  

                    CRYPT_KEY));  

        } catch (Exception e) {  

        }  

        return null;  

    }  

 

    /** 

     * 加密 

     *  

     * @param data 

     * @return 

     * @throws Exception 

     */ 

    public final static String encrypt(String data) {  

        try {  

            return byte2hex(encrypt(data.getBytes(), CRYPT_KEY));  

        } catch (Exception e) {  

        }  

        return null;  

    }  

      

 

2、润乾自定义加解密函数中调用AES类

加密自定义函数:

public class MyEncode extends Function {

 

    public Object calculate(Context ctx, boolean isInput) {

 

       // 判断参数个数

       if (this.paramList.size() < 1) {

           MessageManager mm = EngineMessage.get();

           throw new ReportError("encrypt:"

                  + mm.getMessage("function.missingParam"));

       }

       // 取得第一个参数,默认为表达式,需要把该表达式算出来,结果才是函数的参数值

       Expression param1 = (Expression) this.paramList.get(0);

       if (param1 == null) { // 判断参数是否为空

           MessageManager mm = EngineMessage.get();

           throw new ReportError("encrypt:"

                  + mm.getMessage("function.invalidParam"));

       }

        // 算出第一个参数值

       Object result1 = Variant2.getValue(param1.calculate(ctx, isInput),

              false, isInput);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值