当前位置: 首页 > news >正文

郑州网站优化推广方案湛江麻章区

郑州网站优化推广方案,湛江麻章区,什么网站建设效果好,专业网站建设质量推荐Python 构建壳来启动加密的 SpringBoot Jar 包 通过将 Python 打包成可执行二进制文件来启动 SpringBoot Jar,可以避免 Jar 包容易被反编译的情况。 1.构建加密 SpringBoot jar // 需要传入三个参数: // 第一个:jar 包加密密钥,和…

Python 构建壳来启动加密的 SpringBoot Jar 包

通过将 Python 打包成可执行二进制文件来启动 SpringBoot Jar,可以避免 Jar 包容易被反编译的情况。

1.构建加密 SpringBoot jar

// 需要传入三个参数:
// 第一个:jar 包加密密钥,和后面 launcher.py 里面的 self.encryption_key 相对应;
// 第二个:未加密的 jar 包;
// 第三个:已加密的 jar 包;java -jar JarEncryptor-1.0-SNAPSHOT.jar [b9e8c40dc6ca4eb9928930344812daf4] [origin.jar] [ecrypted.jar]

JarEncryptor-1.0-SNAPSHOT.jar 源码如下。

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class JarEncryptor {private static final String ALGORITHM = "AES/CBC/PKCS5Padding";public static void main(String[] args) throws Exception {// # 此处是密钥,和下面构建 launcher.bin 的 Python 脚本密钥相同,可自行修改,但需要和下面保持一致String encryptionKey = args[0];String inputFile = args[1];String outputFile = args[2];// 生成密钥和 IVbyte[] key = generateKey(encryptionKey);byte[] iv = generateIv(encryptionKey);// 加密文件encryptFile(inputFile, outputFile, key, iv);System.out.println("JAR encrypted successfully");System.out.println("Python launcher command:");System.out.printf("python launcher.py %s%n", outputFile);}private static byte[] generateKey(String seed) throws NoSuchAlgorithmException {MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hash = digest.digest(seed.getBytes());// 取前 32 字节作为 AES-256 密钥byte[] key = new byte[32];System.arraycopy(hash, 0, key, 0, 32);return key;}private static byte[] generateIv(String seed) throws NoSuchAlgorithmException {MessageDigest digest = MessageDigest.getInstance("MD5");return digest.digest(seed.getBytes());}private static void encryptFile(String inputPath, String outputPath, byte[] key, byte[] iv) throws Exception {Cipher cipher = Cipher.getInstance(ALGORITHM);SecretKeySpec keySpec = new SecretKeySpec(key, "AES");IvParameterSpec ivSpec = new IvParameterSpec(iv);cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);try (FileInputStream in = new FileInputStream(inputPath);FileOutputStream out = new FileOutputStream(outputPath)) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {byte[] encrypted = cipher.update(buffer, 0, bytesRead);out.write(encrypted);}byte[] encrypted = cipher.doFinal();out.write(encrypted);}}}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xxx.com</groupId><artifactId>JarEncryptor</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><packaging>jar</packaging><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><!--生成的jar中,不要包含pom.xml和pom.properties这两个文件--><addMavenDescriptor>true</addMavenDescriptor><manifest><mainClass>com.xxx.jar.encryptor.JarEncryptor</mainClass></manifest></archive></configuration></plugin></plugins></build></project>

2.构建 libhidejar.so

用来构建 linux 环境变量库,用来隐藏 java -jar 后面的真实的 jar 包路径。

# 创建 hide_jar_path.c 文件,内容如下:
vim hide_jar_path.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int (*_main) (int, char * *, char * *);
static int pretend_main(int argc, char **argv, char **env)
{char tmp[200];strcpy(tmp, argv[1]);strncpy(argv[1], "", strlen(argv[1]));argv[1] = tmp;char tmp2[200];strcpy(tmp2, argv[argc-1]);strncpy(argv[argc-1], "", strlen(argv[argc-1]));argv[argc-1] = tmp2;return _main(argc, argv, env);
}int (*orig_start_main)(int (*main)(int, char **, char **),int argc,char **argv,void (*init) (void),void (*fini) (void),void (*_fini) (void),void (*stack_end));int __libc_start_main(int (*main)(int, char **, char **),int argc, char **argv,void (*init)(void),void (*fini)(void),void (*_fini)(void),void (*stack_end))
{orig_start_main = dlsym(RTLD_NEXT, "__libc_start_main");_main = main;return orig_start_main(pretend_main, argc, argv, init, fini, _fini, stack_end);
}

通过如下命令构建

# 系统没有 gcc 环境的,需要先安装 gcc 环境gcc -shared -fPIC -o libhidejar.so hide_jar_path.c -ldl

3.构建 launcher.bin

注意,构建操作应该在和实际运行环境相同的 Linux 操作系统上进行。依赖 pycryptodomenuitka,可以通过 pip 进行安装。新建 launcher.py 脚本,内容如下。

# 安装依赖库
pip install pycryptodome
pip install nuitka# 新建 launcher.py 脚本,输入如下内容
vim launcher.py
#!/usr/bin/env python3
import argparse
import hashlib
import os
import signal
import subprocess
import sys
import tempfilefrom Crypto.Cipher import AES
from Crypto.Util.Padding import unpadclass JarLauncher:def __init__(self):self.process = Noneself.temp_dir = Noneself._setup_signal_handlers()# 此处是密钥,和上面构建加密 SpringBoot Jar 相同,可自行修改,但需要和上面保持一致self.encryption_key = 'b9e8c40dc6ca4eb9928930344812daf4'def _setup_signal_handlers(self):"""设置信号处理器确保资源清理"""signal.signal(signal.SIGINT, self._handle_signal)signal.signal(signal.SIGTERM, self._handle_signal)def _handle_signal(self, signum, frame):"""处理终止信号"""print(f"\nReceived signal {signum}, terminating...")self.cleanup()sys.exit(1)def _get_encryption_key(self):"""从安全位置获取加密密钥"""# 实际使用中可以从环境变量、密钥管理服务或加密配置文件中获取key_seed = self.encryption_key# 使用 SHA-256 生成固定长度的密钥return hashlib.sha256(key_seed.encode()).digest()[:32]  # AES-256需要32字节def _get_iv(self):"""获取初始化向量(IV)"""# 可以与密钥一起存储或使用固定值(降低安全性但简化实现)iv_seed = self.encryption_keyreturn hashlib.md5(iv_seed.encode()).digest()  # 16字节def decrypt_jar(self, encrypted_path, key, iv):"""解密 JAR 文件"""with open(encrypted_path, 'rb') as f:encrypted_data = f.read()cipher = AES.new(key, AES.MODE_CBC, iv)try:return unpad(cipher.decrypt(encrypted_data), AES.block_size)except ValueError as e:print(f"Decryption failed: {str(e)}")print("Possible causes: incorrect key/IV or corrupted file")sys.exit(1)def execute_jar(self, jar_data, java_args=None):"""执行 JAR 文件"""self.temp_dir = tempfile.mkdtemp(prefix='jar_launcher_')temp_jar_path = os.path.join(self.temp_dir, 'application.jar')try:# 写入临时文件with open(temp_jar_path, 'wb') as f:f.write(jar_data)# 构建 Java 命令cmd = ['java', '-jar']wrapper_jar_file_path = os.path.join(os.path.dirname(__file__), 'WrapperLauncher.jar')ld_reload_path = os.path.join(os.path.dirname(__file__), 'libhidejar.so')if java_args:cmd.extend(java_args.split())cmd.append(wrapper_jar_file_path)env = os.environ.copy()env["LD_PRELOAD"] = ld_reload_path# 该环境变量和 WrapperLauncher 中相对应,要改则需要一起改env["AWESOME_JAR_XXX"] = temp_jar_pathself.process = subprocess.Popen(cmd,stdout=sys.stdout,stderr=sys.stderr,stdin=sys.stdin,bufsize=1,universal_newlines=True,env=env)# 等待进程结束return self.process.wait()except Exception as e:print(f"Failed to execute JAR: {str(e)}")return 1def cleanup(self):"""清理资源"""if self.process and self.process.poll() is None:self.process.terminate()try:self.process.wait(timeout=5)except subprocess.TimeoutExpired:self.process.kill()if self.temp_dir and os.path.exists(self.temp_dir):try:import shutilshutil.rmtree(self.temp_dir)except Exception as e:print(f"Warning: Failed to clean temp directory: {str(e)}")def main():parser = argparse.ArgumentParser(description='SpringBoot JAR Launcher')parser.add_argument('--jar-file', help='Path to the encrypted JAR file', default='')parser.add_argument('--java-args', help='Additional Java VM arguments', default='')args = parser.parse_args()launcher = JarLauncher()try:# 获取密钥key = launcher._get_encryption_key()iv = launcher._get_iv()# 解密 JARprint("Decrypting JAR file...")jar_file = args.jar_fileif not jar_file:jar_file = os.path.join(os.path.dirname(__file__), 'application.jar')jar_data = launcher.decrypt_jar(jar_file, key, iv)# 执行 JARprint("Starting application...")exit_code = launcher.execute_jar(jar_data, args.java_args)sys.exit(exit_code)except Exception as e:print(f"Fatal error: {str(e)}", file=sys.stderr)launcher.cleanup()sys.exit(1)finally:launcher.cleanup()if __name__ == '__main__':main()

通过如下命令进行构建。

python3 -m nuitka --standalone --onefile --output-dir=out \--include-data-files=[your path of jar encrypted]=application.jar \--include-data-files=./WrapperLauncher-1.0.0-SNAPSHOT.jar=WrapperLauncher.jar \--include-data-files=./libhidejar.so=libhidejar.so \launcher.py

构建成功后,在 out 目录里面会有 launcher.bin 启动类。

4.启动 launcher.bin

launcher.bin 是将 Springboot Jar 包含在内的二进制文件,增加逆向的难度。

./launcher.bin [--jar-file=your external encrypted jar] [--java-args="[your extra args]"]

在这里插入图片描述

启动完成后,是看不到解密后的 jar 路径的。

5.WrapperLauncher

WrapperLauncher 是通过环境变量获取实际的 jar 路径,通过类加载器加载实际的 springboot jar 包,增加一层寻找真实 jar 的障碍。下面是其源码和 pom.xml 配置

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;public class WrapperLauncher {public static void main(String[] args) throws Exception {// 该环境变量和 launcher.py 中相对应,要改则需要一起改String awesomeJarPath = System.getenv("AWESOME_JAR_XXX");URL jarUrl = new File(awesomeJarPath).toURI().toURL();URLClassLoader loader = new URLClassLoader(new URL[]{jarUrl});Class<?> mainClass = loader.loadClass("org.springframework.boot.loader.JarLauncher");Method mainMethod = mainClass.getMethod("main", String[].class);mainMethod.invoke(null, (Object) args);}}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xxx.com</groupId><artifactId>WrapperLauncher</artifactId><version>1.0.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><packaging>jar</packaging><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><addMavenDescriptor>true</addMavenDescriptor><manifest><mainClass>com.xxx.wrapper.launcher.WrapperLauncher</mainClass></manifest></archive></configuration></plugin></plugins></build></project>
http://www.yayakq.cn/news/79057/

相关文章:

  • 设计师网站崩了南京做网站的客户电话
  • 盐城网站建设培训班wordpress 别名 自动
  • 去哪找网站建设公司好wordpress怎么实现注册登录
  • 网站域名备案流程淘掌门官方网站
  • 包装设计网站素材wordpress 文章分类id
  • 网站的优点和缺点哪里有营销型网站
  • 聊城网站空间公司网站建设公司怎么选
  • 长沙seo网站建设费用50个优秀网站
  • 百姓网网站建设苏州建设网站的公司
  • 两学一做网站源码一 网站建设管理基本情况
  • wordpress整站手机端重庆网址大全
  • 南京网站建设知识wordpress 远程ftp
  • 上海网站建设价位淘宝客做动态广告的网站
  • 全面的网站建设企业网站布局960
  • 山东建设银行招聘网站怎么改wordpress的html5
  • 商丘建设网站大气企业网站模板
  • as.net 网站开发视频教程wordpress默认邮件文件夹
  • 义乌外贸公司建站进入公众号继续阅读下一章
  • 沥林网站建设马甲比较好自己搭建app托管平台
  • 网站开发转移合同百度seo排名优化软件
  • 免费网站推广服务做企业网站的意义
  • 国外h5分享网站云彩网站
  • 个人门户网站模板下载织梦网站程序安装
  • 17一起广州做网站wordpress删除文章数据库
  • 建设各网站需要多久培训体系包括四大体系
  • 房地产行业网站建设报价方案如何设计制作一般企业网站
  • 做公司网站需要会什么科目长春朝阳学校网站建设
  • 外贸网站商城施工企业的项目负责人应当对( )负责
  • 西安专业建设网站wordpress 截取中文
  • 您的网站空间已过期完整开发网站需要什么