• 详细解密finereport9.0破解版中的报表执行过程


    finereport9.0破解版|finereport10.0破解并发数|finereport授权注册|FineBI5.0破解lic

    nereport9.0破解版|finereport10.0破解并发数|finereport授权注册|FineBI5.0破解lic


    详细解密finereport9.0破解版中的报表执行过程

    在报表开发工具FineReport中,报表的执行过程大体可分为两步:1、报表计算;2、页面转换。

    报表计算过程:先读取我们的sql语句,将完整的sql语句传至数据库服务器,由数据库返回数据给报表服务器,报表服务器进行数据列的扩展、汇总、关联、公式运算等计算,最终生成报表结果。

    页面转换过程:报表计算完成后生成xml页面,需要转换为html页面才能在浏览器中查看。

    针对这一过程FineReport是可以实时监控的。监控方法是将服务器的log输出级别设为“普通信息”,就能在控制台上看到每一步使用的时间。

    1. 设置日志输出级别

    修改日志输出级别为“显示普通信息”,如下图设计器中设置:

     

    2. 查看报表执行过程

    2.1 打开模板

    finereport9.0破解版|finereport10.0完美破解补丁|finereport授权注册|FineBI5.0破解lic

    打开FR设计器,打开里面自带的模板:%FR_HOME%WebReportWEB-INF eportletsgettingstarted.cpt

    2.2 清空finereport9.0破解版日志

    点击分页预览前,先清空日志。

    3. 浏览器端访问报表

    点击分页预览,输入参数条件后,点击查询;

    等到报表在浏览器上完全展示出来后,查看日志窗口的信息:

     

    从日志中我们可以对报表的执行过程进行实时监控。

    报表插件finereport9.0破解版中密码加密RSA加密算法

    在使用数据集进行身份认证时,密码存在数据库中,认证时用户输入的密码与数据库中密码相同则认证通过,若数据库被破解了则对系统造成威胁,怎样保证系统安全呢?下面就通过报表插件FineReport来介绍一下RSA加密算法。

    工具/材料

    报表插件FineReport7.1.1

    大小:148.2M 适用平台:windows/linux

    操作方法

      • 01

        加载bcprov-jdk14-146.jar驱动包
        RSA加密使用的第三方包,放到工程web-inf/lib文件夹下即可,如果没有驱动可点击bcprov-jdk14-146.jar驱动包下载。
        注:JBOSS服务器下,使用的第三方加密包,提示报错:Can not parse the BC Provider。需要将此包bcprov-jdk14-146.jar从报表工程下移入到JBOSS默认jar包路径下即可。

      • 02

        调用js文件
        RSA文件夹为前端js加密时需要调用js文件,因此需要将Barrett.js、BigInt.js、RSA.js放到工程目录下如:WebReport/js,新建js文件夹放入js文件,如果没有此js文件可点击rsa/js下载。

      • 03

        定义RSA加密类
        定义RSAUtil.java类文件,先运行类中generateKeyPair()方法,会在服务器D盘中生成一个随机的RSAKey.txt文件,保存公钥和密钥,每访问一次这个方法会刷新一次txt文件。
        package com.fr.privilege;
        import java.io.ByteArrayOutputStream;
        import java.io.FileInputStream;
        import java.io.FileOutputStream;
        import java.io.ObjectInputStream;
        import java.io.ObjectOutputStream;
        import java.math.BigInteger;
        import java.security.KeyFactory;
        import java.security.KeyPair;
        import java.security.KeyPairGenerator;
        import java.security.NoSuchAlgorithmException;
        import java.security.PrivateKey;
        import java.security.PublicKey;
        import java.security.SecureRandom;
        import java.security.interfaces.RSAPrivateKey;
        import java.security.interfaces.RSAPublicKey;
        import java.security.spec.InvalidKeySpecException;
        import java.security.spec.RSAPrivateKeySpec;
        import java.security.spec.RSAPublicKeySpec;
        import javax.crypto.Cipher;
        /**
        * RSA 工具类。提供加密,解密,生成密钥对等方法。
        * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
        *
        */
        public class RSAUtil {
        /**
        * * 生成密钥对 *
        *
        * @return KeyPair *
        * @throws EncryptException
        */
        public static KeyPair generateKeyPair() throws Exception {
        try {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
        new org.bouncycastle.jce.provider.BouncyCastleProvider());
        final int KEY_SIZE = 1024;// 没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        KeyPair keyPair = keyPairGen.generateKeyPair();
        saveKeyPair(keyPair);
        return keyPair;
        } catch (Exception e) {
        throw new Exception(e.getMessage());
        }
        }
        public static KeyPair getKeyPair() throws Exception {
        FileInputStream fis = new FileInputStream("C:/RSAKey.txt");
        ObjectInputStream oos = new ObjectInputStream(fis);
        KeyPair kp = (KeyPair) oos.readObject();
        oos.close();
        fis.close();
        return kp;
        }
        public static void saveKeyPair(KeyPair kp) throws Exception {
        FileOutputStream fos = new FileOutputStream("C:/RSAKey.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        // 生成密钥
        oos.writeObject(kp);
        oos.close();
        fos.close();
        }
        /**
        * * 生成公钥 *
        *
        * @param modulus *
        * @param publicExponent *
        * @return RSAPublicKey *
        * @throws Exception
        */
        public static RSAPublicKey generateRSAPublicKey(byte[] modulus,
        byte[] publicExponent) throws Exception {
        KeyFactory keyFac = null;
        try {
        keyFac = KeyFactory.getInstance("RSA",
        new org.bouncycastle.jce.provider.BouncyCastleProvider());
        } catch (NoSuchAlgorithmException ex) {
        throw new Exception(ex.getMessage());
        }
        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(
        modulus), new BigInteger(publicExponent));
        try {
        return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
        } catch (InvalidKeySpecException ex) {
        throw new Exception(ex.getMessage());
        }
        }
        /**
        * * 生成私钥 *
        *
        * @param modulus *
        * @param privateExponent *
        * @return RSAPrivateKey *
        * @throws Exception
        */
        public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,
        byte[] privateExponent) throws Exception {
        KeyFactory keyFac = null;
        try {
        keyFac = KeyFactory.getInstance("RSA",
        new org.bouncycastle.jce.provider.BouncyCastleProvider());
        } catch (NoSuchAlgorithmException ex) {
        throw new Exception(ex.getMessage());
        }
        RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(
        modulus), new BigInteger(privateExponent));
        try {
        return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
        } catch (InvalidKeySpecException ex) {
        throw new Exception(ex.getMessage());
        }
        }
        /**
        * * 加密 *
        *
        * @param key
        *            加密的密钥 *
        * @param data
        *            待加密的明文数据 *
        * @return 加密后的数据 *
        * @throws Exception
        */
        public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {
        try {
        Cipher cipher = Cipher.getInstance("RSA",
        new org.bouncycastle.jce.provider.BouncyCastleProvider());
        cipher.init(Cipher.ENCRYPT_MODE, pk);
        int blockSize = cipher.getBlockSize();// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024
        // 加密块大小为127
        // byte,加密后为128个byte;因此共有2个加密块,第一个127
        // byte第二个为1个byte
        int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
        int leavedSize = data.length % blockSize;
        int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
        : data.length / blockSize;
        byte[] raw = new byte[outputSize * blocksSize];
        int i = 0;
        while (data.length - i * blockSize > 0) {
        if (data.length - i * blockSize > blockSize)
        cipher.doFinal(data, i * blockSize, blockSize, raw, i
        * outputSize);
        else
        cipher.doFinal(data, i * blockSize, data.length - i
        * blockSize, raw, i * outputSize);
        // 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到
        // ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了
        // OutputSize所以只好用dofinal方法。
        i++;
        }
        return raw;
        } catch (Exception e) {
        throw new Exception(e.getMessage());
        }
        }
        /**
        * * 解密 *
        *
        * @param key
        *            解密的密钥 *
        * @param raw
        *            已经加密的数据 *
        * @return 解密后的明文 *
        * @throws Exception
        */
        public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
        try {
        Cipher cipher = Cipher.getInstance("RSA",
        new org.bouncycastle.jce.provider.BouncyCastleProvider());
        cipher.init(cipher.DECRYPT_MODE, pk);
        int blockSize = cipher.getBlockSize();
        ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
        int j = 0;
        while (raw.length - j * blockSize > 0) {
        bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
        j++;
        }
        return bout.toByteArray();
        } catch (Exception e) {
        throw new Exception(e.getMessage());
        }
        }
        /**
        * * *
        *
        * @param args *
        * @throws Exception
        */
        public static void main(String[] args) throws Exception {
        RSAPublicKey rsap = (RSAPublicKey) RSAUtil.generateKeyPair()
        .getPublic();
        String test = "hello world";
        byte[] en_test = encrypt(getKeyPair().getPublic(), test.getBytes());
        System.out.println("123:" + new String(en_test));
        byte[] de_test = decrypt(getKeyPair().getPrivate(), en_test);
        System.out.println(new String(de_test));
        }
        }

      • 04

        定义TestPasswordValidatorRSA.java密码验证类
        定义一个类,命名为TestPasswordValidatorRSA.java,扩展于AbstractPasswordValidator,重写其中密码验证方法encodePassword,先把输入的密码进行翻转,然后再进行加密,返回密码进行验证,具体代码如下:
        package com.fr.privilege;
        import com.fr.privilege.providers.dao.AbstractPasswordValidator;
        public class TestPasswordValidatorRSA extends AbstractPasswordValidator{
        //@Override
        public String encodePassword( String clinetPassword) {
        try {
        //对密码进行翻转如输入ab翻转后为ba
        StringBuffer sb = new StringBuffer();
        sb.append(new String(clinetPassword));
        String bb = sb.reverse().toString();
        //进行加密
        byte[] en_test = RSAUtil.encrypt(RSAUtil.getKeyPair().getPublic(),bb.getBytes());
        //进行解密,如果数据库里面保存的是加密码,则此处不需要进行解密
        byte[] de_test = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_test);
        //返回加密密码
        clinetPassword=new String(de_test);
        } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
        return clinetPassword; //即获取加密密码再与数据库密码匹配。
        }
        @Override
        public boolean validatePassword(String arg0, String arg1) {
        // TODO Auto-generated method stub
        return false;
        }
        }

      • 05

        编译类文件
        首先编译RSAUtil.java类文件在服务器的D盘生成RSAKey.txt文件,再编译TestPasswordValidatorRSA.java类,把编译后的class文件放到项目工程web-inf/classes/com/fr/privilege文件夹中。

      • 06

        登陆Login.jsp页面设置
        客户端请求到登录页面,随机生成一字符串,此随机字符串作为密钥加密密码,如下代码:
        <%@page contentType="text/html" pageEncoding="UTF-8"%>
        <%@page import="com.fr.privilege.providers.dao.RSAUtil"%>
        <%!public String Testmo() {
        String module = "";
        try {
        java.security.interfaces.RSAPublicKey rsap = (java.security.interfaces.RSAPublicKey) RSAUtil
        .getKeyPair().getPublic();
        module = rsap.getModulus().toString(16);
        } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
        return module;
        }%>
        <%!public String Testem() {
        String empoent = "";
        try {
        java.security.interfaces.RSAPublicKey rsap = (java.security.interfaces.RSAPublicKey) RSAUtil
        .getKeyPair().getPublic();
        empoent = rsap.getPublicExponent().toString(16);
        } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
        return empoent;
        }%>
        <html>
        <head>
        <script type="text/javascript"
        src="ReportServer?op=emb&resource=finereport.js"></script>
        <script type="text/javascript" src="js/RSA.js"></script>
        <script type="text/javascript" src="js/BigInt.js"></script>
        <script type="text/javascript" src="js/Barrett.js"></script>
        <script type="text/javascript">
        function bodyRSA()
        {
        setMaxDigits(130);
        var a = "<%=Testmo()%>";
        var b = "<%=Testem()%>";
        key = new RSAKeyPair(b,"",a);
        }
        function doSubmit() {
        bodyRSA();
        var username = FR.cjkEncode(document.getElementById("username").value); //获取输入的用户名
        var password = FR.cjkEncode(document.getElementById("password").value);  //获取输入的参数
        .ajax({
        url : "ReportServer?op=auth_login&fr_username=" + username + "&fr_password=" + password,   //将用户名和密码发送到报表认证地址op=auth_login
        data : {__redirect__ : 'false'},
        complete : function(res) {
        var jo = FR.jsonDecode(res.responseText);
        if(jo.url) {
        window.location=jo.url+ "&_=" + new Date().getTime();   //认证成功跳转页面,因为ajax不支持重定向所有需要跳转的设置
        }
        else{
        alert("用户名密码错误!")  //认证失败
        }
        }
        })
        }
        </script>
        </head>
        <body>
        <p>
        请登录
        </p>
        <form name="login" method="POST">
        <p>
        用户名:
        <input id="username" type="text" />
        </p>
        <p>
        密 码:
        <input id="password" type="password" />
        </p>
        <input type="button" value="登录" onclick="doSubmit()" />
        </form>
        </body>
        </html>

      • 07

        管理平台设置
        访问报表触发加密文件需要在管理平台>权限配置中设置,勾选自定义密码加密,在文本框中输入com.fr.privilege.TestPasswordValidatorRSA即可调用。
        如上所有设置完之后,RSA加密算法基本上就设置完成。

      • 【finereport9.0破解版】从搭建到部署

      • 概念

        从上篇博客【FineReport】介绍(链接)中,可以了解到FineReport可以做什么,那么如果我们要进行FineReport的开发,需要有一个环境,最后再进行部署

        这里部署分为两种,一种是独立部署,FineReport制作的决策系统可以作为一个独立的系统部署,同时,它也嵌入到我们已有的系统当中,详情可以参考官方帮助文档,这里简单说一下独立部署

        准备环境

        1. 定位到软件安装的根目录下,把所有内容都复制到一个新的文件夹;
        2. 打开软件,点击[文件] —> [切换工作目录] —> [其它] —> [+] —> [本地目录] —> 选择刚建立的新文件夹,选择 ./WebReport/WEB-INF 文件夹做为目录;
        3. 可以把原有的那些报表删掉,文件夹可以通过点击 [打开所在文件夹] 然后删除,这样就可以有一个纯净的环境,当然也可以留下作为参考;

        部署发布

        1. 开发完成之后,定位到自己建立的那个文件夹;
        2. 把WebReport文件夹这个拷到Tomcat的webapps文件夹下;
        3. 运行tomcat,在浏览器输入 http://localhost:8080/WebReport/ReportServer?reportlet=GettingStarted.cpt(这个地址是根据具体项目名字和报表而定的,WebReport是你的项目名字,GettingStarted.cpt是你具体的报表名字,这个可以通过在开发的时候预览看到相应的名字)

        小结

        FineReport不仅可以独立部署,同时可以嵌入到我们现有的项目中部署,为我们分析显示数据提供了很多帮助;

        现在看来,对于一些小的系统,FineReport直连数据库,可以很快的开发;

        当然,对于大型系统,还有大数据,这也是个很好的选择,毕竟,帆软的切入点就在数据上面;

        诚如FineReport所言:让数据成为生产力

    转载自:https://www.cnblogs.com/FineReport/p/9638776.html

  • 相关阅读:
    GirdView实现折叠式效果
    asp.net MVC出错解决
    C#如何实现从内存中加载程序集
    从线程池看《操作系统》专业课的作用【转自杨中科学生大本营】
    JavaScript的10个非常有用的方法【转】
    JQuery最佳实践:JQuery自定义事件的应用
    C#的委托事件在winform窗体中实现传值备忘
    asp.net异步获取datatable并显示
    ASP.NET 请求处理流程【转】
    温故而知新:WinForm/Silverlight多线程编程中如何更新UI控件的值
  • 原文地址:https://www.cnblogs.com/sunzhihua/p/11237042.html
Copyright © 2020-2023  润新知