UE4 UnrealPak加密功能(配置AES encrypt key)

news2024/11/24 20:02:39

本文的重点在于如何使用UnrealPak的加密功能,以及相关的UE4源代码学习。本文参考了:https://www.cnblogs.com/shiroe/p/14803859.html 。

设置密钥

在编辑、项目设置中找到下面栏目,并点击“生成新的加密密钥”,就可以为Unreal Pak配置Encryption了。

保存后,观察到工程路径下 Config\DefaultCrypto.ini 具有这些配置:

[/Script/CryptoKeys.CryptoKeysSettings]
EncryptionKey=6A/h1s12rbKctPXXXXXXXXXX
bEncryptPakIniFiles=True
bEncryptPakIndex=True
bEncryptUAssetFiles=False
bEncryptAllAssetFiles=False
SigningPublicExponent=
SigningModulus=
SigningPrivateExponent=
bEnablePakSigning=False

其中的 bEncryptPakIniFiles 表示是否加密ini文件。bEncryptPakIndex 对应 UnrealPak.exe 的 -encryptindex 开关,它和 -encrypt 的区别是:

在UE4中,`-encryptindex`和`-encrypt`是两个命令行参数,用于对Pak文件进行加密的不同方式。

1. `-encryptindex`:这个参数用于对Pak文件中的索引进行加密。Pak文件的索引包含了文件名、文件路径和文件偏移等信息。通过对索引进行加密,可以防止未经授权的访问和修改Pak文件中的资源。

2. `-encrypt`:这个参数用于对Pak文件中的资源文件进行加密。资源文件包括游戏的纹理、模型、声音等实际的资源数据。通过对资源文件进行加密,可以保护这些资源的安全性,防止未经授权的访问和使用。

区别在于,`-encryptindex`只对Pak文件的索引进行加密,而`-encrypt`则对Pak文件中的资源文件进行加密。索引加密主要用于保护Pak文件的结构和元数据,而资源文件加密则用于保护实际的资源数据。

这两个参数可以根据项目的需求和安全性要求进行选择和组合使用。通常情况下,建议至少对资源文件进行加密,以保护游戏的核心资源。而对索引进行加密可以提供额外的保护层,增加Pak文件的安全性。

需要注意的是,加密Pak文件会增加加载和解密的开销,可能会对游戏的性能产生一定影响。因此,在使用这些参数时,需要权衡安全性和性能之间的平衡,并根据项目的需求进行选择。

在UnrealPak.exe的介绍中,可以看到只要指定了 “-enginedir=” 和 “-projectdir=”  ,就会使用 DefaultCrypto.ini 中的Key来作为密钥,参考 https://www.cnblogs.com/shiroe/p/14803859.html,如下:

unrealpak PAK_NAME.pak -create=ResponseFile -compress -encrypt -encryptindex -aes=32bit_AESKey

// 在\Config\DefaultEncryption.ini文件中查找AES的密钥,4.26 提示用 -cryptokeys
-encryptindex -encryptionini -enginedir="<EngineDir>" -projectdir="<GameDir>" -platform=Windows

// 新版使用,可将项目设置中的 Encryption Key 填入到json中
//json 格式为 { "EncryptionKey": {"Key": "tmAjE6/depliVQgG3XgI60bwrQE2iGgg5n8VRPXrGm0="} }
-encrypt -encryptindex -compress -cryptokeys=<Crypto.json>

接下来我尝试找到【指定了 “-enginedir=” 和 “-projectdir=”  就会使用 DefaultCrypto.ini 中的Key来作为密钥】所对应的源代码:

Engine\UE4\Source\Developer\PakFileUtilities\Private\PakFileUtilities.cpp 中的  void LoadKeyChain(const TCHAR* CmdLine, FKeyChain& OutCryptoSettings) 中的

void LoadKeyChain(const TCHAR* CmdLine, FKeyChain& OutCryptoSettings)
{
// ……

		if (FParse::Value(CmdLine, TEXT("projectdir="), ProjectDir, false)
			&& FParse::Value(CmdLine, TEXT("enginedir="), EngineDir, false)
			&& FParse::Value(CmdLine, TEXT("platform="), Platform, false))
		{
			UE_LOG(LogPakFile, Warning, TEXT("A legacy command line syntax is being used for crypto config. Please update to using the -cryptokey parameter as soon as possible as this mode is deprecated"));

			FConfigFile EngineConfig;

			FConfigCacheIni::LoadExternalIniFile(EngineConfig, TEXT("Engine"), *FPaths::Combine(EngineDir, TEXT("Config\\")), *FPaths::Combine(ProjectDir, TEXT("Config/")), true, *Platform);
			bool bDataCryptoRequired = false;
			EngineConfig.GetBool(TEXT("PlatformCrypto"), TEXT("PlatformRequiresDataCrypto"), bDataCryptoRequired);

			if (!bDataCryptoRequired) // 【MarkA】
			{
				return;
			}

			FConfigFile ConfigFile;
			FConfigCacheIni::LoadExternalIniFile(ConfigFile, TEXT("Crypto"), *FPaths::Combine(EngineDir, TEXT("Config\\")), *FPaths::Combine(ProjectDir, TEXT("Config/")), true, *Platform);
			bool bSignPak = false;

// ……

(代码块1)

调试“加密生成Pak的过程”

"G:\TheTestingPak2.pak" -Create="{我的项目中的某个Pak命令}_PakCommands.txt" -AlignForMemoryMapping=0 -compress -encrypt -encryptindex -compressionformats=Oodle -encryptionini -projectdir="{我的项目目录}" -enginedir="G:\St\EngineSource" -platform=Android

如果不明白其中的PakCommands.txt的含义,请自行了解,它配置了“需要打包的资源”。

选择 UnrealPak 进行调试,并将 Programe Arguments改为上述指令。

一个小坎

断点断在“代码块1”处,发现在 MarkA 处就进不来了,bDataCryptoRequired 始终是 false,也就是 以下这个ini字段始终是false(或没配置)。

TEXT("PlatformCrypto"), TEXT("PlatformRequiresDataCrypto")

(图:一处阻碍,其中的 bDataCryptoRequired 始终是 false,暂不知道在哪里配置)

解决方法:根据 http://t.csdnimg.cn/RHylE 的介绍,如果我希望快速设置这个值,我需要得知其“Ini层级”,断点查看 EngineConfig.SourceIniHierarchy 得知,只需要创建一个 UserEngine.ini 如下图红框所示,并配置上该字段,如图2,再次运行,就能通过了 ( :D ) 。

[PlatformCrypto]
PlatformRequiresDataCrypto=true

(图2)

最后如愿以偿进入到了我们的目标代码,并能看到密钥:

走完整个过程,看到了日志输出:

LogPakFile: Display: Creating pak G:\TheTestingPak4.pak.
LogPakFile: Display: Using encryption key 'Default' [00000000000000000000000000000000]
LogPakFile: Display: CompressionFormats in priority order: Oodle, Zlib
LogDerivedDataCache: Warning: bShared: 0, data cache Path: ../../../Engine/DerivedDataCache 
LogDerivedDataCache: Warning: CreateFileSystemDerivedDataBackend
LogPakFile: Display: CompressionFormat 0 [Oodle] : 0 files, 0 -> 0 bytes
LogPakFile: Display: CompressionFormat 1 [Zlib] : 0 files, 0 -> 0 bytes
LogPakFile: Display: CompressionFormat 2 [None] : 4 files, 27297821 -> 27297821 bytes
LogPakFile: Display: Added 4 files, 27298849 bytes total, time 0.19s.
LogPakFile: Display: PrimaryIndex size: 176 bytes
LogPakFile: Display: PathHashIndex size: 64 bytes
LogPakFile: Display: FullDirectoryIndex size: 320 bytes
LogPakFile: Display: Encryption - ENABLED
LogPakFile: Display:   Files: 4
LogPakFile: Display:   Index: Encrypted (176 bytes, 0.00MB)
LogPakFile: Display:   Total: 27297856 bytes (26.03MB)
LogPakFile: Display: Unreal pak executed in 600.237102 seconds

尝试用UnrealPak.exe去验证一下这个新产生的包,发现List不出来,到这里,就能说明产生的Pak是加密的。

G:\>G:\St\{我的项目}\Engine\Binaries\Win64\UnrealPak.exe -List TheTestingPak.pak
LogTemp: Display: FCustomCryptoModule::StartupModule
LogPakFile: Display: Using command line for crypto configuration
LogWindows: Error: === Critical error: ===
LogWindows: Error:
LogWindows: Error: Fatal error: [File:D:/{我的项目}/EngineSource/Engine/Source/Runtime/PakFile/Private/IPlatformFilePak.cpp] [Line: 339]
LogWindows: Error: Failed to find requested encryption key 00000000000000000000000000000000
LogWindows: Error:
LogWindows: Error:
LogWindows: Error:
LogHeavyTaskMonitor: Warning: FHeavyTaskMonitor TaskKey GLog_TearDown ,TaskPath GLog_TearDown , TaskTime 37.61
FHeavyTaskMonitor TaskKey GLog_TearDown ,TaskPath GLog_TearDown , TaskTime 37.61

到这里,我们就知道如何使用AES加密Pak了,后面的内容是关于UnrealPak.exe解密的追加调试研究,非重点。

UnrealPak.exe无法解密出“已加密的Pak”

原本,我以为有了Key,就可以用UnrealPak.exe罗列出(“-List” 指令)或者解析出(“-Extract” 指令)已加密的Pak中的内容,但是我折腾了很久,我始终无法通过 UnrealPak.exe 的指令进行解密。始终会报错:

【命令行】

G:\>G:\St\DFMEditor\Engine\Binaries\Win64\UnrealPak.exe  TheTestingPak.pak  -Extract G:\{我的解压后目录}  -cryptokey=G:\key.json 【具体内容见后文】

【输出】
LogTemp: Display: FCustomCryptoModule::StartupModule
LogPakFile: Display: Using command line for crypto configuration
LogWindows: Error: === Critical error: ===
LogWindows: Error:
LogWindows: Error: Fatal error: [File:D:/StableEditor/EngineSource/Engine/Source/Runtime/PakFile/Private/IPlatformFilePak.cpp] [Line: 339]
LogWindows: Error: Failed to find requested encryption key 00000000000000000000000000000000
LogWindows: Error:
LogWindows: Error:
LogWindows: Error:
LogHeavyTaskMonitor: Warning: FHeavyTaskMonitor TaskKey GLog_TearDown ,TaskPath GLog_TearDown , TaskTime 37.69
FHeavyTaskMonitor TaskKey GLog_TearDown ,TaskPath GLog_TearDown , TaskTime 37.69

G:\key.json的内容是:

{ "EncryptionKey": {
    "Name": "null",
    "Guid": "null",
    "Key": "6A/h1s12rbKctPygBwBcw+Q7FaidXaWzfn/NE4IsjbA="
    }
}

最终结论是:没有办法通过UnrealPak.exe直接解压出加密的Pak内容。我查询到的资料有:

1、如何在项目中而非用UnrealPak.exe 来进行解密:

I can't encrypt and load my external .pak at runtime - Programming & Scripting - Epic Developer Community Forums

2、主要EncryptionKey的GUID是 "Guid":"00000000-0000-0000-0000-000000000000",只有 SecondaryEncryptionKeys 才可能非零:

UE工具链配置与开发技巧 | 循迹研究室

3、 在UnrealPak.exe中主动重载 GUID

-encryptionkeyoverrideguid (override the encryption key guid used for encrypting data in this pak file)

https://www.cnblogs.com/shiroe/p/14803859.html

4、一个成功能够解密出加密内容的帖子,但是内容比较复杂,没有看出是怎么做到的
How I Extracted an Unreal Engine Game’s WWise Audio - Just Still

5、"EncryptionKey" 中的 Guid 配置为"null"

https://github.com/allcoolthingsatoneplace/UnrealPakTool/blob/master/Readme.md

6、有人遇到同样问题 But it still using default keys

LogPakFile: Display: Using encryption key 'Default' [00000000000000000000000000000000]

https://gbatemp.net/threads/how-to-unpack-and-repack-unreal-engine-4-files.531784/page-14

相关代码是搜索 FNamedAESKey::Guid 的设值的地方(下图的红色的引用处),都是 Guid() 。

至于为什么游戏内可以成功解密出来用呢?现在我还不了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1953087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K210视觉识别模块学习笔记7:多线程多模型编程识别

今日开始学习K210视觉识别模块: 图形化操作函数 亚博智能 K210视觉识别模块...... 固件库: canmv_yahboom_v2.1.1.bin 训练网站: 嘉楠开发者社区 今日学习使用多线程、多模型来识别各种物体 这里先提前说一下本文这次测试实验的结果吧&#xff1a;结果是不太成…

ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH?

ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH? 目录 ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH? 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/61780…

详解程序的预处理与编译与连接

文章目录 1.程序的翻译环境和执行环境2.详解编译链接2.1 翻译环境2.2 编译本身也分为几个阶段2.3 运行环境 3.预处理详解3.1 预处理符号3.2 \#define3.2.1 \#define 定义标识符3.2.2 \#define定义宏3.2.3 \#define 替换规则 3.2.4 \#和\#\#3.2.5 带副作用的宏参数3.2.6 宏和函数…

数据结构之判断二叉树是否为搜索树(C/C++实现)

文章目录 判断二叉树是否为搜索树方法一&#xff1a;递归法方法二&#xff1a;中序遍历法总结 二叉树是一种非常常见的数据结构&#xff0c;它在计算机科学中有着广泛的应用。二叉搜索树&#xff08;Binary Search Tree&#xff0c;简称BST&#xff09;是二叉树的一种特殊形式&…

【VUE】封装一个追随鼠标的漂浮组件框架

红色箭头代表鼠标位置&#xff0c;蓝色区域跟随鼠标出现&#xff0c;鼠标进行其他操作的时候&#xff0c;蓝色区域隐藏。 vue全码 <template><divmousemove"updatePosition"mouseleave"hideDiv"class"container":style"{ positi…

AXI总线

目录 一、AXI接口特点二、AXI接口的握手机制2.1 握手原理2.2 握手机制的三种情形 三、AXI接口的通道3.1 AXI4-Stream3.1.1 通道信号3.1.2 数据字节类型3.1.3 流格式 3.2 AXI4-Lite和AXI4-Full3.1.1 读地址通道3.1.2 读数据通道3.1.3 写地址通道3.1.4 写数据通道3.1.5 写响应通道…

MybatisPlus分页插件

分页查询是一个很常见的需求&#xff0c;故Mybatis-Plus提供了一个分页插件&#xff0c;使用它可以十分方便的完成分页查询。下面介绍Mybatis-Plus分页插件的用法&#xff0c;详细信息可参考官方链接。 配置分页插件 创建com.atguigu.hellomp.config.MPConfiguration配置类&a…

奇异值分解(SVD)时间复杂度分析与优化

奇异值分解是一种矩阵分解的方法&#xff0c;大学线性代数里面也讲过奇异值分解的方法&#xff0c;因此这是一个为大家所熟知的算法。 1 SVD 时间复杂度分析 给定一个 m n m \times n mn 的矩阵 a \boldsymbol{a} a&#xff0c;按照下面公式做分解&#xff0c;其中 Σ \S…

python语言利用Tkinter实现GUI计算器|(二)优化计算器:过滤用户不合理的输入

python语言利用Tkinter实现GUI计算器 python语言利用Tkinter实现GUI计算器|&#xff08;一&#xff09;计算器基本功能设计 python语言利用Tkinter实现GUI计算器|&#xff08;二&#xff09;优化计算器 python语言利用Tkinter实现GUI计算器|&#xff08;三&#xff09;pyinstal…

python在类中手动定义标准化输出函数

在深度学习等训练框架中&#xff0c;有时候需要对模型的名称、参数量、训练进度、中间结果等进行标准化输出&#xff0c;从而方便实时查看代码运行情况&#xff0c;这时&#xff0c;可以在类中手动定义如下标准化的输出函数&#xff0c;然后在需要输出的地方进行调用即可。 首…

免费【2024】springboot 超市货品信息管理系统

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

修复SteamUI.dll加载失败的指南,快速修复failed to load steamui.dll

在使用Steam平台进行游戏下载、安装和运行时&#xff0c;可能会遇到一些系统错误&#xff0c;比如“failed to load steamui.dll”。这个错误通常意味着Steam的用户界面库文件steamui.dll出现了问题。本文将详细介绍steamui.dll文件的相关信息以及如何修复这一问题。 一.什么是…

vue 开发环境配置

1. nvm 安装 在 github上下载 最新的 nvm 包 https://github.com/coreybutler/nvm-windows/releases或者在 csdn 上下载&#xff08;从github上迁移&#xff0c;方便下载&#xff09;https://download.csdn.net/download/u011171506/89585197 下载后不用修改任何配置&#x…

Opencv学习项目4——手部跟踪

上一篇博客我们介绍了mediapipe库和对手部进行了检测&#xff0c;这次我们进行手部关键点的连线 代码实现 import cv2 import mediapipe as mpcap cv2.VideoCapture(1) mpHands mp.solutions.hands hands mpHands.Hands() mpDraw mp.solutions.drawing_utilswhile True:…

树莓派智能家居中枢

一个先进的枢纽&#xff0c;使智能家居系统更智能、更可定制、更易于控制 Homey Pro由树莓派 Compute Module 4 供电,Homey Pro 为用户提供了一个单一界面,用于控制和监控来自不同品牌的所有智能家居设备。它完全在本地网络上运行,而不是依赖云端,从而实现了最低的延迟、最高的…

对Linux目录结构的补充

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…

【数据结构】哈希表的模拟实现

文章目录 1. 哈希的概念2. 哈希表与哈希函数2.1 哈希冲突2.2 哈希函数2.3 哈希冲突的解决2.3.1 闭散列&#xff08;线性探测&#xff09;2.3.2 闭散列的实现2.3.3 开散列(哈希桶)2.3.4 开散列的实现 2.4 开散列与闭散列比较 1. 哈希的概念 在我们之前所接触到的所有的数据结构…

【C语言项目】 以链表实现的管理系统(注册、登录、对表进行数据操作)

第一次编辑这么长的文章&#xff0c;如果对你有帮助&#xff0c;可以点赞收藏一下一起学习&#xff01;一起进步&#xff01; 目录 一、项目介绍 二、代码介绍 三、小记 四、完整代码 五、输出结果展示 1、成功将终端输入的用户姓名和密码分别存入到.txt文件中 2、登陆成…

cpp学习记录03

结构体 定义&#xff1a;用户自定义符合数据类型&#xff0c;可以包含不同类型的不同成员。 //声明结构体 struct 结构体类型&#xff08;自己起名&#xff09; {成员1类型 成员1名称&#xff1b;。。。成员N类型 成员N名称&#xff1b;} 基本用法&#xff08;类似class&…

探索 Electron:构建用户友好的登录页面流程

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…