发明内容
本申请提供了一种对Java内容仓库数据的加密处理方法、装置和设备,用于解决现有的JSR-170规范没有包含对内容仓库数据进行加密操作的API,存在在实现对Java内容仓库数据加密时,只能修改Java内容仓库具体实现程序源代码,会让加密功能拓展跟程序源代码直接耦合,降低程序可维护性和可移植性,不方便程序更新管理发布,增加程序维护成本的技术问题。
有鉴于此,本申请第一方面提供了一种对Java内容仓库数据的加密处理方法,包括:
基于JavaAgent结合Javaassit进行自定义被代理类织入,所述被代理类包括使用getString和getStream方法的javax.jcr.Value实现类、使用getValue方法的javax.jcr.Property实现类和使用save方法的javax.jcr.Item实现类;
基于ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将所述加密操作标识设置为无效;
在将数据导入Java内容仓库前,通过所述加密操作标识判断是否需要执行所述javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作;
基于ThreadLocal在所述javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在所述javax.jcr.Property的getValue方法执行后将所述解密操作标识设置为无效;
在访问Java内容仓库数据时,先通过所述javax.jcr.Property实现类的etValue方法获取当前节点数据对象,再通过所述javax.jcr.Value实现类的所述getString和getStream方法访问所述当前节点数据对象的数据值;
基于所述javax.jcr.Value实现类的代理类,对所述getString和getStream方法进行代理,通过所述解密操作标识判断是否需要执行解密操作,若所述解密操作标识有效,则执行解密操作。
可选地,所述基于JavaAgent结合Javaassit进行自定义被代理类织入,包括:
自定义java.lang.instrument.ClassFileTransformer接口的实现类;
重写transform方法,使用Javassist对实现类进行自定义转换;
使用premain方法加载自定义的ClassFileTransformer接口的实现类,在MANIFEST.MF文件里指定premain方法所在类的路径。
可选地,所述重写transform方法,使用Javassist对实现类进行自定义转换,包括:
使用Javaassit的ClassPool.getDefault().get()获取当前已经加载java虚拟机里的被代理类;
使用Javaassit的CtClass.getDeclaredMethod()先获取当前类的需要被代理的方法;
使用Javaassit的CtNewMethod.copy()将所述当前类的需要被代理的方法复制,然后将需要被代理的方法重命名,成为被代理方法调用的方法,而复制生成的新方法使用被代理方法的名称和参数,成为代理方法,代理方法替换被代理方法称为新的方法调用入口;
使用Javaassit的CtMethod.setBody()自定义代理方法内容,将自定义的代理类的方法织入到方法体里;
使用Javaassit的CtClass.addMethod()将代理方法增加到被代理类当中;
使用Javaassit的CtClass.toBytecode()生成新的字节码,作为transform方法返回值。
可选地,所述在将数据导入Java内容仓库前,通过所述加密操作标识判断是否需要执行所述javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作,包括:
在将数据导入Java内容仓库前,判断加密操作标识判断是否需要执行所述javax.jcr.Item实现类的save方法进行数据保存;
对使用所述getString方法拿到的字符串数据,若加密操作标识有效,则先进行base64编码转换,再执行加密操作;
对使用所述getStream方法拿到的二级制数据,若加密操作标识有效,则直接执行加密操作。
可选地,所述基于所述javax.jcr.Value实现类的代理类,对所述getString和getStream方法进行代理,通过所述解密操作标识判断是否需要执行解密操作,若所述解密操作标识有效,则执行解密操作,包括:
基于所述javax.jcr.Value实现类的代理类,对所述getString和getStream方法进行代理;
若所述解密操作标识有效,对于使用所述getString方法拿到的字符串数据,需要先进行解密,然后进行base64编码转换,获取原始字符串数据;
若所述解密操作标识有效,对于使用所述getStream方法拿到的二级制数据,则直接进行解密获取到原始数据。
本申请第二方面提供了一种对Java内容仓库数据的加密处理装置,包括:
代理类织入模块,用于基于JavaAgent结合Javaassit进行自定义被代理类织入,所述被代理类包括使用getString和getStream方法的javax.jcr.Value实现类、使用getValue方法的javax.jcr.Property实现类和使用save方法的javax.jcr.Item实现类;
加密标识配置模块,用于基于ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将所述加密操作标识设置为无效;
加密判断模块,用于在将数据导入Java内容仓库前,通过所述加密操作标识判断是否需要执行所述javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作;
解密标识配置模块,用于基于ThreadLocal在所述javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在所述javax.jcr.Property的getValue方法执行后将所述解密操作标识设置为无效;
访问模块,用于在访问Java内容仓库数据时,先通过所述javax.jcr.Property实现类的etValue方法获取当前节点数据对象,再通过所述javax.jcr.Value实现类的所述getString和getStream方法访问所述当前节点数据对象的数据值;
解密判断模块,用于基于所述javax.jcr.Value实现类的代理类,对所述getString和getStream方法进行代理,通过所述解密操作标识判断是否需要执行解密操作,若所述解密操作标识有效,则执行解密操作。
可选地,所述代理类织入模块,包括:
自定义子模块,用于自定义java.lang.instrument.ClassFileTransformer接口的实现类;
重写子模块,用于重写transform方法,使用Javassist对实现类进行自定义转换;
加载子模块,用于使用premain方法加载自定义的ClassFileTransformer接口的实现类,在MANIFEST.MF文件里指定premain方法所在类的路径。
可选地,所述重写子模块具体用于:
使用Javaassit的ClassPool.getDefault().get()获取当前已经加载java虚拟机里的被代理类;
使用Javaassit的CtClass.getDeclaredMethod()先获取当前类的需要被代理的方法;
使用Javaassit的CtNewMethod.copy()将所述当前类的需要被代理的方法复制,然后将需要被代理的方法重命名,成为被代理方法调用的方法,而复制生成的新方法使用被代理方法的名称和参数,成为代理方法,代理方法替换被代理方法称为新的方法调用入口;
使用Javaassit的CtMethod.setBody()自定义代理方法内容,将自定义的代理类的方法织入到方法体里;
使用Javaassit的CtClass.addMethod()将代理方法增加到被代理类当中;
使用Javaassit的CtClass.toBytecode()生成新的字节码,作为transform方法返回值。
可选地,所述加密判断模块,具体用于:
在将数据导入Java内容仓库前,判断加密操作标识判断是否需要执行所述javax.jcr.Item实现类的save方法进行数据保存;
对使用所述getString方法拿到的字符串数据,若加密操作标识有效,则先进行base64编码转换,再执行加密操作;
对使用所述getStream方法拿到的二级制数据,若加密操作标识有效,则直接执行加密操作;
所述解密判断模块具体用于:
基于所述javax.jcr.Value实现类的代理类,对所述getString和getStream方法进行代理;
若所述解密操作标识有效,对于使用所述getString方法拿到的字符串数据,需要先进行解密,然后进行base64编码转换,获取原始字符串数据;
若所述解密操作标识有效,对于使用所述getStream方法拿到的二级制数据,则直接进行解密获取到原始数据。
本申请第三方面提供了一种对Java内容仓库数据的加密处理设备,所述设备包括处理器以及存储器:
所述存储器用于存储程序代码,并将所述程序代码传输给所述处理器;
所述处理器用于根据所述程序代码中的指令执行第一方面任一种所述的对Java内容仓库数据的加密处理方法。
从以上技术方案可以看出,本申请实施例具有以下优点:
本申请中提供了一种对Java内容仓库数据的加密处理方法,包括:基于JavaAgent结合Javaassit进行自定义被代理类织入,被代理类包括使用getString和getStream方法的javax.jcr.Value实现类、使用getValue方法的javax.jcr.Property实现类和使用save方法的javax.jcr.Item实现类;基于ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将加密操作标识设置为无效;在将数据导入Java内容仓库前,通过加密操作标识判断是否需要执行javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作;基于ThreadLocal在javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在javax.jcr.Property的getValue方法执行后将解密操作标识设置为无效;在访问Java内容仓库数据时,先通过javax.jcr.Property实现类的etValue方法获取当前节点数据对象,再通过javax.jcr.Value实现类的getString和getStream方法访问当前节点数据对象的数据值;基于javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,通过解密操作标识判断是否需要执行解密操作,若解密操作标识有效,则执行解密操作。本申请中提供的对Java内容仓库数据的加密处理方法,通过在程序启动时增加JavaAgent参数去控制是否启动代理方法,实现了松耦合、无侵入和可插拔的代理效果,在不修改被代理类源代码和class文件的情况下,对被代理类实现代理功能,解决了现有的JSR-170规范没有包含对内容仓库数据进行加密操作的API,存在在实现对Java内容仓库数据加密时,只能修改Java内容仓库具体实现程序源代码,会让加密功能拓展跟程序源代码直接耦合,降低程序可维护性和可移植性,不方便程序更新管理发布,增加程序维护成本的技术问题。
具体实施方式
为了使本技术领域的人员更好地理解本申请方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
为了便于理解,请参阅图1,本申请提供了一种对Java内容仓库数据的加密处理方法的一个实施例,包括:
步骤101、基于JavaAgent结合Javaassit进行自定义被代理类织入,被代理类包括使用getString和getStream方法的javax.jcr.Value实现类、使用getValue方法的javax.jcr.Property实现类和使用save方法的javax.jcr.Item实现类。
需要说明的是,本申请实施例中,首先使用JavaAgent技术结合字节码编辑工具Javaassit实现自定义被代理类织入,被代理类和方法包括javax.jcr.Value实现类的getString和getStream方法、javax.jcr.Property实现类的getValue方法和javax.jcr.Item实现类的save方法。
步骤102、基于ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将加密操作标识设置为无效。
需要说明的是,在执行javax.jcr.Item的save方法将数据到Java内容仓库时,当前***可能会正在执行其它有需要调用javax.jcr.Value实现类的getString和getStream方法,所以需要设置一个线程变量标识,通过这个标识去判断是否需要去执行代理类的方法,保证了当前***业务稳定性和操作兼容性。利用已经设置好的javax.jcr.Item实现类的代理类,使用java自带的ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将该加密操作标识设置为无效,保证加密操作作用域仅限于当前执行保存操作线程。
步骤103、在将数据导入Java内容仓库前,通过加密操作标识判断是否需要执行javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作。
需要说明的是,在执行javax.jcr.Item的save方法过程中,会调用javax.jcr.Value实现类的getString和getStream方法获取需要保存的数据,利用已经设置好的javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,先判断当前加密操作标识是否有效,如果有效就执行加密操作,否则就跳过不处理。
步骤104、基于ThreadLocal在javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在javax.jcr.Property的getValue方法执行后将解密操作标识设置为无效。
需要说明的是,利用已经设置好的javax.jcr.Property实现类的代理类,使用java自带的ThreadLocal在javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在在javax.jcr.Property的getValue方法执行后将该解密操作标识设置为无效,保证解密操作作用域仅限于当前执行数据访问操作线程。
步骤105、在访问Java内容仓库数据时,先通过javax.jcr.Property实现类的etValue方法获取当前节点数据对象,再通过javax.jcr.Value实现类的getString和getStream方法访问当前节点数据对象的数据值。
需要说明的是,***在访问Java内容仓库数据时,会先通过javax.jcr.Property实现类的getValue方法获取当前节点数据对象,然后通过avax.jcr.Value实现类的getString,getStream等方法去访问该对象数据值。
步骤106、基于javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,通过解密操作标识判断是否需要执行解密操作,若解密操作标识有效,则执行解密操作。
需要说明的是,利用已经设置好的javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,先判断当前解密操作标识是否有效,如果有效,如果有效就执行解密操作,否则就跳过不处理。
本申请实施例中提供的对Java内容仓库数据的加密处理方法,通过在程序启动时增加JavaAgent参数去控制是否启动代理方法,实现了松耦合、无侵入和可插拔的代理效果,在不修改被代理类源代码和class文件的情况下,对被代理类实现代理功能,解决了现有的JSR-170规范没有包含对内容仓库数据进行加密操作的API,存在在实现对Java内容仓库数据加密时,只能修改Java内容仓库具体实现程序源代码,会让加密功能拓展跟程序源代码直接耦合,降低程序可维护性和可移植性,不方便程序更新管理发布,增加程序维护成本的技术问题。
为了便于理解,请参阅图2,本申请提供了一种对Java内容仓库数据的加密处理方法的另一个实施例,包括:
步骤201、自定义java.lang.instrument.ClassFileTransformer接口的实现类。
步骤202、重写transform方法,使用Javassist对实现类进行自定义转换。
步骤203、使用premain方法加载自定义的ClassFileTransformer接口的实现类,在MANIFEST.MF文件里指定premain方法所在类的路径。
需要说明的是,使用JavaAgent技术结合字节码编辑工具javaassit实现自定义被代理类织入可以包括以下内容:
1、自定义java.lang.instrument.ClassFileTransformer接口的实现类,该类可以在java虚拟机加载类时对类进行重新定义;
2、重写transform方法,在方法里使用javassist工具对类进行自定义转换;
转换过程的处理步骤可以是:
1)、使用javaassit的ClassPool.getDefault().get()获取当前已经加载java虚拟机里的被代理类。
2)、使用javaassit的CtClass.getDeclaredMethod()先获取当前类的需要被代理的方法。
3)、使用javaassit的CtNewMethod.copy()将该方法复制一份,然后将需要被代理的方法重命名,成为被代理方法调用的方法,而复制生成的新方法使用被代理方法的名称和参数,成为代理方法,代理方法替换被代理方法称为新的方法调用入口。
4)、使用javaassit的CtMethod.setBody()自定义代理方法内容,将自定义的代理类的方法织入到方法体里,本方案代理类的方法都使用了静态方法,可以直接在代理方法里调用,在代理方法里先调用自定义代理类的前置方法,然后调用被代理方法,然后调用自定义代理类的后置方法,被代理方法使用try,catch语句包围,在出现异常时会调用自定义代理类的异常处理方法,在被代理方法被调用的前后,异常时织入代理方法,实现方法调用各个切面的代理效果。
5)、使用javaassit的CtClass.addMethod()将代理方法增加到被代理类当中。
6)、使用javaassit的CtClass.toBytecode()生成新的字节码,作为transform方法返回值,以此方式在不修改被代理类源代码和class文件的情况下,对被代理类实现代理功能。
3、使用premain方法加载自定义的ClassFileTransformer接口的实现类,在MANIFEST.MF文件里指定premain方法所在类的路径。
步骤204、基于ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将加密操作标识设置为无效。
需要说明的是,本申请实施例中的步骤204与上一实施例中的步骤102一致,在此不再进行赘述。
步骤205、在将数据导入Java内容仓库前,通过加密操作标识判断是否需要执行javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作。
需要说明的是,在执行javax.jcr.Item的save方法过程中,会调用javax.jcr.Value实现类的getString和getStream方法获取需要保存的数据,利用已经设置好的javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,先判断当前加密操作标识是否有效,如果有效就执行加密操作,否则就跳过不处理。对使用getString方法拿到的字符串数据,若加密操作标识有效,则先进行base64编码转换,再执行加密操作;对使用getStream方法拿到的二级制数据,若加密操作标识有效,则直接执行加密操作。
步骤206、基于ThreadLocal在javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在javax.jcr.Property的getValue方法执行后将解密操作标识设置为无效。
需要说明的是,本申请实施例中的步骤206与上一实施例中的步骤104一致,在此不再进行赘述。
步骤207、在访问Java内容仓库数据时,先通过javax.jcr.Property实现类的etValue方法获取当前节点数据对象,再通过javax.jcr.Value实现类的getString和getStream方法访问当前节点数据对象的数据值。
需要说明的是,本申请实施例中的步骤207与上一实施例中的步骤105一致,在此不再进行赘述。
步骤208、基于javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,通过解密操作标识判断是否需要执行解密操作,若解密操作标识有效,则执行解密操作。
需要说明的是,利用已经设置好的javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,先判断当前解密操作标识是否有效,如果有效,如果有效就执行解密操作,否则就跳过不处理。若解密操作标识有效,对于使用getString方法拿到的字符串数据,需要先进行解密,然后进行base64编码转换,获取原始字符串数据;若解密操作标识有效,对于使用getStream方法拿到的二级制数据,则直接进行解密获取到原始数据。
本申请基于JavaAgent技术实现对Java内容仓库数据加密功能拓展,不需要对Java内容仓库具体实现程序源代码进行修改,能达到高效,低耦合且可插拨的效果,增强了程序可维护性和可移植性,方便程序更新管理发布。而且适用于任何java程序,兼容那些不被spring容器托管的java实例,所以在兼容性上也相对于现有技术有了优化。
为了便于理解,请参阅图3,本申请提供了一种对Java内容仓库数据的加密处理装置的实施例,包括:
代理类织入模块,用于基于JavaAgent结合Javaassit进行自定义被代理类织入,被代理类包括使用getString和getStream方法的javax.jcr.Value实现类、使用getValue方法的javax.jcr.Property实现类和使用save方法的javax.jcr.Item实现类。
加密标识配置模块,用于基于ThreadLocal在javax.jcr.Session的save方法执行前将加密操作标识设置为有效,在javax.jcr.Session的save方法执行后将加密操作标识设置为无效。
加密判断模块,用于在将数据导入Java内容仓库前,通过加密操作标识判断是否需要执行javax.jcr.Item实现类的save方法进行数据保存,若加密操作标识有效,则执行加密操作。
解密标识配置模块,用于基于ThreadLocal在javax.jcr.Property的getValue方法执行前将解密操作标识设置为有效,在javax.jcr.Property的getValue方法执行后将解密操作标识设置为无效。
访问模块,用于在访问Java内容仓库数据时,先通过javax.jcr.Property实现类的etValue方法获取当前节点数据对象,再通过javax.jcr.Value实现类的getString和getStream方法访问当前节点数据对象的数据值。
解密判断模块,用于基于javax.jcr.Value实现类的代理类,对getString和getStream方法进行代理,通过解密操作标识判断是否需要执行解密操作,若解密操作标识有效,则执行解密操作。
进一步地,代理类织入模块,包括:
自定义子模块,用于自定义java.lang.instrument.ClassFileTransformer接口的实现类;
重写子模块,用于重写transform方法,使用Javassist对实现类进行自定义转换;
加载子模块,用于使用premain方法加载自定义的ClassFileTransformer接口的实现类,在MANIFEST.MF文件里指定premain方法所在类的路径。
进一步地,重写子模块具体用于:
使用Javaassit的ClassPool.getDefault().get()获取当前已经加载java虚拟机里的被代理类;
使用Javaassit的CtClass.getDeclaredMethod()先获取当前类的需要被代理的方法;
使用Javaassit的CtNewMethod.copy()将当前类的需要被代理的方法复制,然后将需要被代理的方法重命名,成为被代理方法调用的方法,而复制生成的新方法使用被代理方法的名称和参数,成为代理方法,代理方法替换被代理方法称为新的方法调用入口;
使用Javaassit的CtMethod.setBody()自定义代理方法内容,将自定义的代理类的方法织入到方法体里;
使用Javaassit的CtClass.addMethod()将代理方法增加到被代理类当中;
使用Javaassit的CtClass.toBytecode()生成新的字节码,作为transform方法返回值。
加密判断模块,具体用于:
在将数据导入Java内容仓库前,判断加密操作标识判断是否需要执行javax.jcr.Item实现类的save方法进行数据保存;
对使用getString方法拿到的字符串数据,若加密操作标识有效,则先进行base64编码转换,再执行加密操作;
对使用getStream方法拿到的二级制数据,若加密操作标识有效,则直接执行加密操作;
解密判断模块具体用于:
基于javax.jcr.Value实现类的代理类,对所述getString和getStream方法进行代理;
若解密操作标识有效,对于使用getString方法拿到的字符串数据,需要先进行解密,然后进行base64编码转换,获取原始字符串数据;
若解密操作标识有效,对于使用getStream方法拿到的二级制数据,则直接进行解密获取到原始数据。
本申请中还提供了一种对Java内容仓库数据的加密处理设备的实施例,设备包括处理器以及存储器:
存储器用于存储程序代码,并将程序代码传输给所述处理器;
处理器用于根据程序代码中的指令执行前述的对Java内容仓库数据的加密处理方法实施例中的对Java内容仓库数据的加密处理方法。
在本申请所提供的几个实施例中,应该理解到,所揭露的装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个***,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本申请各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。
所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机***(可以是个人计算机,服务器,或者网络***等)执行本申请各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(英文全称:Read-OnlyMemory,英文缩写:ROM)、随机存取存储器(英文全称:Random Access Memory,英文缩写:RAM)、磁碟或者光盘等各种可以存储程序代码的介质。
以上所述,以上实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围。