一种Java类加密、解密方法及计算机可读存储介质与流程

文档序号:23383153发布日期:2020-12-22 13:47阅读:117来源:国知局
一种Java类加密、解密方法及计算机可读存储介质与流程

本申请涉及计算机程序源代码加密及解密领域,尤其涉及一种java类加密、解密方法及计算机可读存储介质。



背景技术:

代码混淆(obfuscatedcode)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作代码混淆器。相关技术中,已经存在许多种功能各异的代码混淆器。

代码混淆只是设置人类阅读和理解的难度,仍然可以通过反编译工具反编译成可供人类阅读的源代码,而且很多应用使用spring框架或其它依赖注入(dependencyinjection,简称为di)ioc(inversionofcontrol,控制反转)框架,由于框架的需要,不能任意对函数的类名、方法名、注解、变量进行修改,因此,代码混淆无法实现真正有效的加密。

字节码加密则是通过加密算法,直接将字节码class文件加密后存储并运行,加密后的字节码文件无法被java虚拟机(jvm)直接识别并运行,必须通过定制类加载器(classloader)或结合java虚拟机工具接口(javavirtualmachinetoolinterface,简称为jvmti)技术,使得classloader在类加载阶段将字节码文件动态解密后才能正常运行。

相关技术中,一种常用的java字节码类文件加密解密的方法是通过非对称加密的方式将class加密,并结合jvmti机制拦截jvm类加载的过程,实现在类加载的过程中动态解密。

这种加解密的方式大致需要以下几个步骤或要素:1)加密算法(使用公开或私有的加密算法即可,但通常使用非对称加密,如rsa);2)提前生成一对密钥(公钥和私钥),公钥用于加密,私钥用于解密;3)使用加密算法和公钥提前将需要加密的java应用的所有java类文件提前加密,并将原类文件删除;4)私钥随加密后的应用部署;5)运行时使用加入下面的参数以启动jvmti解密:agentpath:/path/to/decrypt.so,加入该参数后即可完成拦截classloader的类加载方法并实现内存中动态解密(解密过程中需要用到私钥)。

该方案实现的加密解密过程是比较安全的,但该方案导致很多流行的java框架(如springframework、hibernate、apachetomcat)在启动阶段无法扫描这些加密的class,从而导致java应用无法正常启动。



技术实现要素:

为了解决上述技术问题或者至少部分地解决上述技术问题,本申请提供了一种java类加密、解密方法及计算机可读存储介质。

第一方面,本申请提供了一种java类加密方法,包括:生成密钥;使用上述密钥对第一字节码类文件进行加密,得到第一字节码类文件密文;生成与上述第一字节码类文件同名的第二字节码类文件,其中,上述第二字节码类文件具有与上述第一字节码类文件相同的扫描特征,以使字节码工具将上述第二字节码类文件当作上述第一字节码文件来扫描;将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件;使用上述第二字节码类文件替换上述第一字节码类文件。

在某些实施例中,将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件,包括:在上述第二字节码类文件中设置一个或多个私有字符串类型常量字段;对上述第一字节码类文件密文进行编码,得到第一字节码类文件密文编码;将上述第一字节码类文件密文编码写入上述一个或多个私有字符串类型常量字段。

在某些实施例中,将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件,包括:将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件的常量池中。

在某些实施例中,上述第二字节码类文件的方法签名、注解及类属性与上述第一字节码类文件相同。

第二方面,本申请提供了一种java类解密方法,包括:通过字节码工具对第二字节码类文件预扫描启动,其中,上述第二字节码类文件与第一字节码类文件同名,并具有与上述第一字节码类文件相同的扫描特征,以使上述字节码工具将上述第二字节码类文件当作上述第一字节码文件来扫描;通过类加载器加载上述第二字节码类文件;在类加载器加载上述第二字节码类文件的过程中,拦截上述类加载器的加载过程,并根据java程序运行时启动参数中的代理路径,启动解密过程;在上述解密过程中,从上述第二字节码类文件中获取上述第一字节码类文件的第一字节码类文件密文,其中,上述第一字节码类文件的第一字节码类文件密文被以字符串类型常量写入上述第二字节码类文件中;使用密钥对上述第一字节码类文件密文进行解密,得到上述第一字节码类文件;将上述第一字节码类文件提供给上述类加载器,以使上述类加载器加载上述第一字节码类文件。

在某些实施例中,在上述解密过程中,从上述第二字节码类文件中获取上述第一字节码类文件的第一字节码类文件密文,包括:在上述解密过程中,从上述第二字节码类文件的常量池中获取上述第一字节码类文件的第一字节码类文件密文。

在某些实施例中,在上述解密过程中,拦截上述类加载器的加载过程,包括:通过jvmti机制拦截上述类加载器的加载过程。

在某些实施例中,上述第二字节码类文件的方法签名、注解及类属性与上述第一字节码类文件相同。

第三方面,本申请提供了一种计算机可读存储介质,上述计算机可读存储介质上存储有java类加密程序,上述java类加密程序被处理器执行时实现java类加密方法的步骤。

第四方面,本申请提供了一种计算机可读存储介质,上述计算机可读存储介质上存储有java类解密程序,上述java类解密程序被处理器执行时实现java类解密方法的步骤。

本申请实施例提供的上述技术方案与现有技术相比具有如下优点:本申请实施例提供的该技术方案,实现了对java应用和java框架均完全透明的加解密过程。

附图说明

此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本申请的实施例,并与说明书一起用于解释本申请的原理。

为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。

图1为本申请实施例提供的java类加密方法一种实施方式的流程图;

图2为本申请实施例提供的java类解密方法一种实施方式的流程图;

图3为本申请实施例提供的使用rsa非对称加密算法的java类加密方法的流程图;

图4为本申请实施例提供的使用rsa非对称加密算法的java类解密方法的流程图;

图5为本申请实施例的java类加密装置一种实施方式的结构框图;

图6为本申请实施例的java类解密装置一种实施方式的结构框图;以及

图7为本申请实施例的计算机设备一种实施方式的硬件结构示意图。

具体实施方式

应当理解,此处所描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。

在后续的描述中,使用用于表示元件的诸如“模块”、“部件”或“单元”的后缀仅为了有利于本申请的说明,其本身没有特定的意义。因此,“模块”、“部件”或“单元”可以混合地使用。

本文中,字节码是java虚拟机执行的一种虚拟指令格式,字节码文件由java源代码编译而来。

jvmti是java虚拟机所提供的native编程(c/c++)接口,可以探查jvm内部状态和控制jvm应用程序的执行,并可通过动态修改jvm运行时类字节码实现增强的目的。可实现的功能包括但不限于:获取jvm运行时状态,替换和修改类定义等。

类加载器(classloader),是用来加载java类到java虚拟机中的一种加载器。

springframework简称spring,是一个基于ioc和aop的构架多层j2ee系统的框架,包括但不限于springboot,springweb,springbeans等。

apachetomcat是apache软件基金会(apachesoftwarefoundation)的jakarta项目中的一个核心项目,是一种开源javaweb应用服务器。

hibernate是一个开源的对象关系映射框架,它对jdbc进行了非常轻量级的对象封装,使得java程序员可以灵活的使用对象编程思维来操纵数据库。

字节码工具是java字节码生成和分析的框架,可以用它通过直接操作二进制字节码的方式来动态修改或者动态生成字节码类文件,包括但不限于asm、cglib、javassist以及bcel等。

本申请实施例提供了一种java类加密和解密方法。该方法通过创建一个与原字节码类文件(本文中称为第一字节码类文件)同名的新的字节码类文件(称之为桩class文件,stubclass,仍然为javaclass字节码文件格式,本文中称为第二字节码类文件)。在第二字节码类文件中保留第一字节码类文件相同的扫描特征(例如,方法签名、注解及类属性),同时,将第一字节码类文件加密后的密文内容以字符串类型常量的方式写入桩第二字节码类文件。从而实现对java应用和java框架均完全透明的加解密过程。

下面结合附图对本申请实施例的java类加密和解密方法的一些实施方式进行描述。

图1为本申请实施例提供的java类加密方法一种实施方式的流程图,如图1所示,java加密方法包括步骤s102至步骤s110。

步骤s102,生成密钥。

在某些实施例中,上述步骤s102中,采用对称加密算法生成密钥,加密和解密使用相同密钥。对称加密算反包括但不限于des、3des、aes、desx、blowfish、、rc4、rc5、rc6等。

在某些实施例中,上述步骤s102中,使用非对称加密算法生成密钥,该密钥为密钥对,密钥对包括公钥和私钥,公钥用于加密,私钥用于解密。非对称加密算法包括但不限于rsa、dsa(数字签名用)、ecc(移动设备用)、diffie-hellman、elgamal等。

步骤s104,使用上述密钥对第一字节码类文件进行加密,得到第一字节码类文件密文。

步骤s106,生成与上述第一字节码类文件同名的第二字节码类文件,其中,上述第二字节码类文件具有与上述第一字节码类文件相同的扫描特征,以使字节码工具将上述第二字节码类文件当作上述第一字节码文件来扫描。

步骤s108,将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件。

在某些实施例中,在步骤s108中,将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件的常量池中,以便于在解密时使用字节码工具快速读取第一字节码类文件密文。

在某些实施例中,在步骤s108中,字符串类型常量为私有字符串类型常量,但不限于此。

步骤s110,使用上述第二字节码类文件替换上述第一字节码类文件。

在某些实施例中,上述步骤s108中,将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件,包括:在上述第二字节码类文件中设置一个或多个私有字符串类型常量字段;对上述第一字节码类文件密文进行编码,得到第一字节码类文件密文编码;将上述第一字节码类文件密文编码写入上述一个或多个私有字符串类型常量字段。

在某些实施例中,上述第二字节码类文件的方法签名、注解及类属性与上述第一字节码类文件相同,但不限于此。由此,使得第二字节码类文件与第一字节码文件的扫描特征相同。

图2为本申请实施例提供的java类解密方法一种实施方式的流程图,如图2所示,该java解密方法包括步骤s202至步骤s212。

步骤s202,通过字节码工具对第二字节码类文件预扫描启动,其中,上述第二字节码类文件与第一字节码类文件同名,并具有与上述第一字节码类文件相同的扫描特征,以使上述字节码工具将上述第二字节码类文件当作上述第一字节码文件来扫描。

在本申请实施例中,扫描特征可包括方法签名、注解及类属性,但不限于此。

步骤s204,通过类加载器(classloader)加载上述第二字节码类文件。

步骤s206,在类加载器加载上述第二字节码类文件的过程中,拦截上述类加载器的加载过程,并根据java程序运行时启动参数中的代理路径(agentpath),启动解密过程。

在本申请实施例中,可通过jvmti机制拦截上述类加载器的加载过程。在java程序运行时启动参数中设置代理路径(agentpath),例如,agentpath:/path/to/decrypt.so,其中,decrypt.so为实现jvmti类重新加载机制的解密程序,由该解密程序进行解密过程。

步骤s208,在上述解密过程中,从上述第二字节码类文件中获取上述第一字节码类文件的第一字节码类文件密文,其中,上述第一字节码类文件的第一字节码类文件密文被以字符串类型常量写入上述第二字节码类文件中。

在一些实施例中,第一字节码类文件密文的长度在字符串类型常量的最大长度之内,第一字节码密文被写入一个字符串类型常量,上述步骤s208中,在上述解密过程中,读取该字符串类型常量得到第一字节码类文件密文。该字符串类型常量被写入第二字节码类文件的常量池。

在一些实施例中,第一字节码类文件密文的长度大于字符串类型常量的最大长度,第一字节码类文件密文被切分并写入多个字符串类型常量,上述步骤s208中,读取多个字符串类型常量,合并得到第一字节码类文件密文。

步骤s210,使用密钥对上述第一字节码类文件密文进行解密,得到上述第一字节码类文件。

在本申请实施例中,从运行java应用的服务器获取该密钥,或者从指定地址下载该密钥,但不限于此。

参考本申请的java类加密方法,该密钥可为对称加密算法的密钥,也可以为非对称加密算法的私钥,但不限于此。

步骤s212,将上述第一字节码类文件提供给上述类加载器,以使上述类加载器加载上述第一字节码类文件。

在某些实施例中,步骤s208中,在上述解密过程中,从上述第二字节码类文件的常量池中获取上述第一字节码类文件的第一字节码类文件密文。

下面以使用rsa非对称加密算法进行加密为例对本申请实施例的java类加密和解密方法进行描述。

图3为本申请实施例提供的使用rsa非对称加密算法的java类加密方法的流程图,如图3所示,该方法包括步骤s302至步骤s310。

步骤s302,生成加密用的公钥及私钥密钥对。

在本申请实施例中,私钥随运行的程序部署,放置与待运行程序的服务器上,或可以下载的地方,以在解密时使用。

步骤s304,使用rsa非对称加密算法,使用公钥对原字节码类文件(对应于本文前述的第一字节码类文件)进行加密,获得加密后的密文(对应于本文前述的第一字节码类文件密文)。

步骤s306,使用字节码生成工具(例如asm、javassist等,但不限于此),仿照原字节码类文件,生成一个桩字节码类文件。

该桩字节码类文件具有原字节码类文件的全部属性、方法签名和注解,但是属性值、方法体(方法实现的部分)则置空直接返回,或抛出unsupportedoperationexception。

步骤s308,在桩字节码类文件中,设置私有的string类型常量字段,将密文写入该字段。

例如,私有的string类型常量字段被设置为:encrypted_class_bytes_0,encrypted_class_bytes_1等,但不限于此,并由私有静态全局不可变字符串(privatestaticfinalstring)修饰。

加密后的密文(二进制)内容经编码后(如base64编码,编码方式不限于base64),由于java限制单个string字段最大长度为65535,若密文编码内容超过该长度,则需要自动切分为多个string字段。string类型的常量字段值进入字节码文件的一个名为常量池的段内,方便解密时使用字节码工具快速读取密文内容。

步骤s310,使用上述生成的包含加密内容的桩字节码文件替换原字节码文件。

可选地,在步骤s310之后,使用打包工具打包,也可以将加密程序封装到打包工具里(如maven的package插件),方便与maven及自动化构建工具集成。

图4为本申请实施例提供的使用rsa非对称加密算法的java类解密方法的流程图,如图4所示,该方法包括步骤s402至步骤s410。

步骤s402,在java程序运行时启动参数中加入代理路径(agentpath)。

例如,agentpath:/path/to/decrypt.so,其中,decrypt.so为实现jvmti类重新加载机制的解密程序,有该解密程序进行解密过程。

步骤s404,在java应用启动阶段,类加载器(classloader)加载所有字节码文件前,java框架(spring、apachetomcat、hibernate等)预扫描所有的字节码文件(此时,jvmti解密可能尚未启动),由于加密后的桩字节码文件本身就是完全合法的字节码格式文件,且包含与原字节码类完全一致的方法签名、注解及类变量,因此,上述java框架得以正常启动。

步骤s406,在java应用启动阶段,classloader加载字节码文件时,解密程序(decrypt.so)随jvmti机制启动,并拦截classloader类加载过程,从桩字节码文件的常量池中获取密文,并使用私钥动态实现java类解密。

步骤s408,解密后的原字节码文件被返回给classloader,java应用得以正常运行。

图5为本申请实施例的java类加密装置一种实施方式的结构框图,如图5所示,该java类加密装置包括:加密模块510,用于生成密钥,使用上述密钥对第一字节码类文件进行加密,得到第一字节码类文件密文。生成模块520,与加密模块510连接,用于生成与上述第一字节码类文件同名的第二字节码类文件,将上述第一字节码类文件密文以字符串类型常量写入上述第二字节码类文件,其中,上述第二字节码类文件具有与上述第一字节码类文件相同的扫描特征,以使字节码工具将上述第二字节码类文件当作上述第一字节码文件来扫描。替换模块530,与生成模块520连接,用于使用上述第二字节码类文件替换上述第一字节码类文件。

java类加密装置的加密过程参见本文前述说明,本申请实施例对此不做赘述。

图6为本申请实施例的java类解密装置一种实施方式的结构框图,如图6所示,该java类解密装置包括:字节码工具模块610,用于对第二字节码类文件预扫描启动,其中,上述第二字节码类文件与第一字节码类文件同名,并具有与上述第一字节码类文件相同的扫描特征,以使字节码工具模块610将上述第二字节码类文件当作上述第一字节码文件来扫描。类加载器模块620,用于加载上述第二字节码类文件;拦截与解密模块630,用于在类加载器加载上述第二字节码类文件的过程中,拦截上述类加载器的加载过程,并根据java程序运行时启动参数中的代理路径,启动解密过程;在上述解密过程中,从上述第二字节码类文件中获取上述第一字节码类文件的第一字节码类文件密文,其中,上述第一字节码类文件的第一字节码类文件密文被以字符串类型常量写入上述第二字节码类文件中;使用密钥对上述第一字节码类文件密文进行解密,得到上述第一字节码类文件;将上述第一字节码类文件提供给上述类加载器模块620,以使上述类加载器模块620加载上述第一字节码类文件。

java类解密装置的解密过程参见本文前述说明,本申请实施例对此不做赘述。

本实施例还提供一种计算机设备,如可以执行程序的智能手机、平板电脑、笔记本电脑、台式计算机、机架式服务器、刀片式服务器、塔式服务器或机柜式服务器(包括独立的服务器,或者多个服务器所组成的服务器集群)等。本实施例的计算机设备20至少包括但不限于:可通过系统总线相互通信连接的存储器21、处理器22,如图7所示。需要指出的是,图7仅示出了具有组件21-22的计算机设备20,但是应理解的是,并不要求实施所有示出的组件,可以替代的实施更多或者更少的组件。

本实施例中,存储器21(即可读存储介质)包括闪存、硬盘、多媒体卡、卡型存储器(例如,sd或dx存储器等)、随机访问存储器(ram)、静态随机访问存储器(sram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、可编程只读存储器(prom)、磁性存储器、磁盘、光盘等。在一些实施例中,存储器21可以是计算机设备20的内部存储单元,例如该计算机设备20的硬盘或内存。在另一些实施例中,存储器21也可以是计算机设备20的外部存储设备,例如该计算机设备20上配备的插接式硬盘,智能存储卡(smartmediacard,smc),安全数字(securedigital,sd)卡,闪存卡(flashcard)等。当然,存储器21还可以既包括计算机设备20的内部存储单元也包括其外部存储设备。本实施例中,存储器21通常用于存储安装于计算机设备20的操作系统和各类应用软件,例如java类加密装置的程序代码、java类解密装置的程序代码等。此外,存储器21还可以用于暂时地存储已经输出或者将要输出的各类数据。

处理器22在一些实施例中可以是中央处理器(centralprocessingunit,cpu)、控制器、微控制器、微处理器、或其他数据处理芯片。该处理器22通常用于控制计算机设备20的总体操作。本实施例中,处理器22用于运行存储器21中存储的程序代码或者处理数据,例如运行java类加密装置的程序代码、java类解密装置的程序代码,以实现java类加密方法、java类解密方法。

本实施例还提供一种计算机可读存储介质,如闪存、硬盘、多媒体卡、卡型存储器(例如,sd或dx存储器等)、随机访问存储器(ram)、静态随机访问存储器(sram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、可编程只读存储器(prom)、磁性存储器、磁盘、光盘、服务器、app应用商城等等,其上存储有计算机程序,程序被处理器执行时实现相应功能。本实施例的计算机可读存储介质用于存储java类加密程序或java类解密程序,被处理器执行时实现实实现java类加密方法的步骤,或者实现java类解密方法的步骤。

需要说明的是,在本文中,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者装置不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者装置所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括该要素的过程、方法、物品或者装置中还存在另外的相同要素。

上述本申请实施例序号仅仅为了描述,不代表实施例的优劣。

通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到上述实施例方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如rom/ram、磁碟、光盘)中,包括若干指令用以使得一台终端(可以是手机,计算机,服务器,空调器,或者网络设备等)执行本申请各个实施例所述的方法。

上面结合附图对本申请的实施例进行了描述,但是本申请并不局限于上述的具体实施方式,上述的具体实施方式仅仅是示意性的,而不是限制性的,本领域的普通技术人员在本申请的启示下,在不脱离本申请宗旨和权利要求所保护的范围情况下,还可做出很多形式,这些均属于本申请的保护之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1