Springboot 加密方案探讨
背景
toB 的本地化 java 应用程序,通常是部署在客户机器上,为了保护知识产权,我们需要将核心代码(例如 Lience,Billing,Pay 等)进行加密或混淆,防止使用 jadx 等工具轻易反编译。同时,为了更深层的保护程序,也要防止三方依赖细节被窥探;
业界方案
- ProGuard
- 简介:开源社区有名的免费混淆工具,相较于字节码加密,对性能基本无影响;
- 优势:打包阶段混淆字节码,各种变量方法名都变成了abcdefg 等等无意义的符号,字节码可被反编译,但几乎无法阅读,通常被 Android App 用来防止逆向;
- 不足1:只能混淆部分代码,打包阶段较为耗时,对于三方包混淆,并没有什么好办法。
- 不足2:混淆后的代码,会影响 arthas 工具的使用,导致排查问题变慢。
- 不足3:配置比较复杂,曾经在我司 T 项目上用过,令人眼花缭乱。
- 不足4:无法加密三方依赖所有信息;
- jar-protect
- 简介:一款国人开发的 springboot jar 加密工具;需要配合 javaagent 解密;
- 优势:打包阶段使用 javassist 重写 class 文件;jadx 反编译后看到的都是空方法。反编译后只能看到类信息和方法签名,无法看到具体内容。
- 不足1:使用 DES 方案,对于几百个三方 jar 的场景,加密手段过重,且加密后的不够完整;
- 不足2:类文件放在一个目录(META-INF/.encode/),非常容易类冲突;
- 不足3:无法加密三方依赖所有信息;
- GraalVM
- 简介:Oracle GraalVM 提前将 Java 应用程序编译为独立的二进制文件。与在 Java 虚拟机 (JVM) 上运行的应用程序相比,这些二进制文件更小,启动速度提高了 100 倍,无需预热即可提供峰值性能,并且使用的内存和 CPU 更少, 并且无法反编译。
- 不足:无法支持我司业务程序框架。
- core-lib/xjar
- 简介:国人开源的,基于 golang 的加密工具。使用 maven 插件加密,启动时 golang 解密;性能影响未知。
- 优势:可对所有 class 文件加密。
- 不足1: 加密后 jar 文件体积翻倍;
- 不足2:依赖 golang 编译,依赖 golang 启动;
- 不足3:无法加密三方依赖所有信息;
- 不足4:开源项目,3年未有新提交。
思考:
我们的需求到底是什么?a:保护知识产权。具体手段为:
- 对本司项目代码进行加密,使其无法被 jadx 工具轻易反编译,
- 对本司三方依赖进行加密,使其无法窥探我司三方依赖细节;
但上面的几个项目,基本都是围绕着 class 加密(除了GraalVM),这无法实现我们的第二个需求。
我们的方案
设计目标:
- 将项目三方依赖 jar 进行加密,使其无法使用 jadx 反编译,但运行时会生成解密后的临时文件。
- 将项目本身的 class 进行加密,使其无法使用 jadx 反编译运行时解密后的文件。
- 加密策略要灵活,轻量,对启动速度,包体积,内存消耗,接口性能的影响要控制在 5% 以内;
设计方案:
- 加密时,使用 maven 打包工具,repackage fat jar;将其内部 lib 目录的依赖进行加密;使 jadx 无法反编译;
- 加密时,对于核心业务代码,使用 javassist 工具将其重写,清空方法体,重置属性值;
- 解密jar时,将指定目录的 加密包 解密 到指定目录,并将其放入 springboot classloader classpath 里。
- 解密class时,agent 配合判断是否是加密 class,如果是,则寻找加密 class 文件,找到后解密,返回解密后的 classBytes。
逻辑如下:

注意点:
- javassist 重写方法体时,需要将 lib 里的所有代码都加入 classpool 的 classpath 里。
- javassist 加密后的类,需将其放入到当前 lib 的单独目录进行个例,防止类冲突。
- agent 解密要轻量,不能影响程序性能;
- 三方包的加解密重新打包后,jar 顺序发生变化,较小可能会导致类冲突(比如 log4j)。需要在测试环境验证,如果存在冲突,则需要排包。
End
通过以上方案,我们实现了一个极其轻量的 maven 加密,agent 解密插件。他能够将三方包彻底加密,使 jadx 等工具无法反编译 ,屏蔽我们的三方依赖细节,同时,该插件也可以加密我们的业务 class 代码,使 jadx 无法反编译运行时生成的代码,从而一定程度的保护我们的知识产权;
另外,私有的加密算法,在性能,体积,内存等方便的影响都控制在 5% 以内。
为了防止混淆后的代码影响 arthas 的使用和 bug patch 的应用,我们放弃了混淆方案,只能说是一种权衡与取舍吧。
从软件防破解的角度来理解,通常只能是加大破解的难度,铁了心想要破解的话,就算是 ProGuard 混淆,也无法解决。也许只能用 GraalVM,但不是每一个客户都会用这个。
推荐
Java 扩展点/插件系统,支持热插拔,旨在解决大部分软件的功能定制问题
Springboot 加密方案探讨的更多相关文章
- 移动 H5 首屏秒开优化方案探讨
转载bang大神文章,原文<移动 H5 首屏秒开优化方案探讨>,此文仅仅用做自学与分享! 随着移动设备性能不断增强,web 页面的性能体验逐渐变得可以接受,又因为 web 开发模式的诸多好 ...
- 一个异或加密方案--C语言实现
核心代码: char encrypt( char f , char c) { return f^c; } int OutEncrypt( char *FilePath, char *SecretWor ...
- C# .net 语言加密方案
C# .net 语言加密方案 方案背景 当前C# .net语言的应用范围越来越广泛,IIS 的服务器架构后台代码.桌面应用程序的 winform .Unity3d 的逻辑脚本都在使用.C# .net ...
- lua 代码加密方案
require 实现 require函数在实现上是依次调用package.searchers(lua51中是package.loaders)中的载入函数,成功后返回.在loadlib.c文件里有四个载 ...
- 基于HTTP在互联网传输敏感数据的消息摘要、签名与加密方案
基于HTTP在互联网传输敏感数据的消息摘要.签名与加密方案 博客分类: 信息安全 Java 签名加密AESMD5HTTPS 一.关键词 HTTP,HTTPS,AES,SHA-1,MD5,消息摘要,数 ...
- [原创]aaencode等类似js加密方案破解方法
受http://tieba.baidu.com/p/4104806767 2L启发,不过他说的方法,我没有尝试成功,自己摸索出了一个新方法,在这里分享下. 首先拿aaencode官网的加密字符串作为例 ...
- 基于RSA的WEB前端密码加密方案
受制于WEB页面源码的暴露,因此传统的对称加密方案以及加密密钥都将暴露在JS文件中,同样可以被解密. 目前比较好的解决方案是WEB页面全程或用户登录等关键环节使用HTTPS进行传输. 另外一种解决方案 ...
- 如何保护你的 Python 代码 (一)—— 现有加密方案
https://zhuanlan.zhihu.com/p/54296517 0 前言 去年11月在PyCon China 2018 杭州站分享了 Python 源码加密,讲述了如何通过修改 Pytho ...
- [转帖]如何保护你的 Python 代码 (一)—— 现有加密方案
如何保护你的 Python 代码 (一)—— 现有加密方案 Prodesire Python猫 1周前
- Dataworks批量刷数优化方案探讨
Dataworks批量刷数优化方案探讨 在数据仓库的日常使用中,经常会有批量补数据,或者逻辑调整后批量重跑数据的场景. 批量刷数的实现方式,因调度工具差异而各有不同. Dataworks调度批量刷数局 ...
随机推荐
- 行行AI人才直播第5期:系列课-AI理解及ChatGPT从基础到高级应用
当前,人工智能是全世界研究的重点对象,也是人们茶余饭后讨论的经典话题.自从 OpenAI 发布 ChatGPT-4 之后,似乎无论是在工作.娱乐.甚至是日常生活中,我们都能感受到AI带来的便利和改变. ...
- Java扩展Nginx之二:编译nginx-clojure源码
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 为什么要编译nginx-clojure源码 作为< ...
- [Java基础]String,StringBuffer,StringBuilder的区别
String 和 StringBuffer/StringBuilder应该分开来看 java.lang.String源码中的注释说明 java.lang.StringBuffer源码中的注释说明 ja ...
- 跟着 GPT-4 从0到1学习 Golang 并发机制(三)
目录 一.前言 二.开聊 2.1 关于 goroutine 泄露问题 2.2 内存模型 2.3 Race Detector 检测数据竞争 三.总结 一.前言 话接上回<跟着 GPT-4 从0到1 ...
- 十大功能特性,助力开发者玩转API Explorer
摘要:华为云API Explorer为开发者提供一站式API解决方案统一平台,集成华为云服务所有开放API,支持全量快速检索.可视化调试.帮助文档.代码示例等能力,帮助开发者快速查找.学习API和使用 ...
- 《逆向工程核心原理》之DLL注入
DLL注入 DLL注入指的是向运行中的其他进程强制插入特定的DLL文件.从技术细节来说,DLL注入命令其他进程自行调用LoadLibrary() API,加载(Loading)用户指定的DLL文件.D ...
- Mybatis(Map)
Map 假设,我们的实体类,或者数据库中的表,字段或参数过多,我们应当考虑使用map 创建接口 //万能的mapper,我们不需要知道数据库里面有什么,是一个键值对的表现 //我们只需查询对应的字段 ...
- mysql:EXPLAIN
推荐阅读原文:EXPLAIN用法和结果分析 语法:EXPLAIN SELECT * FROM t1 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句 ...
- linux 软件包:UnixBench 性能测试工具、跑分神器
目录 安装 使用 结果示例 测试项说明 UnixBench是一个类unix系(Unix,BSD,Linux)统下的性能测试工具,一个开源工具,被广泛用与测试linux系统主机的性能.Unixbench ...
- React: 动态添加样式
问题背景 在软件开发过程中,经常会出现动态添加style或className,比如:同一个表格组件在A处调用,需要固定前四列数据, B处调用则不用,那这时候,动态添加元素就派上了用场. 解决方案 如下 ...