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

本文的重点在于如何使用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.mzph.cn/news/876562.shtml

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

相关文章

unity2D游戏开发10生命条脚本

HitPoints 在ScriptableObjects文件夹中创建新的脚本,叫HitPoint using System.Collections; using System.Collections.Generic; using UnityEngine;//创建条目,方便轻松创建HitPoints的实例 [CreateAssetMenu(menuName ="HitPoints")] public class HitPoints :…

锅总介绍CNCF主要目标、全景图及发展历史

一、CNCF简介 云原生计算基金会&#xff08;Cloud Native Computing Foundation&#xff0c;简称 CNCF&#xff09;是一个成立于 2015 年的非营利性组织&#xff0c;隶属于 Linux 基金会。CNCF 的主要目标是通过开源软件推动云原生计算技术的发展和普及&#xff0c;帮助企业更…

四、使用renren-generator生成基本代码

1、打开generator.properties配置文件&#xff0c;修改配置 主要修改包名、模块名、前缀信息 2、修改application.yml配置文件中的数据库信息 3、启动项目 直接访问代码生成器 http://localhost/#generator选择表&#xff0c;点击生成代码即可

Redis-高级实战案例

文章目录 Redis集群崩溃时如何保证秒杀系统高可用1. 冗余与备份2. 故障检测与自动切换3. 降级策略4. 数据一致性5. 客户端缓存6. 异常处理与通知7. 测试与演练8. 服务降级与回滚Redis主从切换导致库存同步异常以及超卖问题主从切换导致的库存同步异常原因:解决方案:秒杀链路中…

怎么使用github上传XXX内所有文件

要将 目录中的所有文件上传到 GitHub&#xff0c;你可以按照以下步骤进行&#xff1a; 创建一个新的 GitHub 仓库 登录到你的 GitHub 账户。 点击右上角的加号&#xff08;&#xff09;&#xff0c;选择 “New repository”。 输入仓库名称&#xff08;例如&#xff1a;202407…

Redux 与 React 状态管理精讲:从基础到实战

引言 Redux 是一个广泛使用的 JavaScript 状态管理库&#xff0c;尤其适用于 React 应用。它提供了一种可预测的方式来管理应用的状态&#xff0c;使得状态的变更变得可控和可追踪。本教程将从 Redux 的基本概念讲起&#xff0c;逐步深入到与 React 结合使用的最佳实践&#x…

滑动窗口练习6-找到字符串中所有字母异位词

题目链接&#xff1a;**. - 力扣&#xff08;LeetCode&#xff09;** 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#…

java Collections.singletonList方法介绍

Collections.singletonList 是 Java 集合框架中的一个静态方法,用于创建一个包含单个元素的不可变列表。这种列表的大小固定为1,并且不允许添加或删除元素。 具体解释 Collections 类: Collections 是一个包含静态方法的类,这些方法用于操作或返回集合。它包括各种实用工具…

《程序猿入职必会(6) · 返回结果统一封装》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

Profinet从站转TCP/IP协议转化网关(功能与配置)

如何将Profinet和TCP/IP网络连接通讯起来呢?近来几天有几个朋友问到这个问题&#xff0c;那么作者在这里统一说明一下。其实有一个不错的设备产品可以很轻易地解决这个问题&#xff0c;名为JM-DNT-PN。接下来作者就从该设备的功能及配置详细说明一下。 一&#xff0c;设备主要…

AIGC(Artificial Intelligence Generated Content)

随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;在各个领域的应用日益广泛&#xff0c;其中也包括前端开发的重要部分——CSS&#xff08;层叠样式表&#xff09;的优化。CSS作为网页设计中控制布局和样式的关键…

el-table合计行更新问题

说明&#xff1a;在使用el-table自带的底部合计功能时&#xff0c;初始界面不会显示合计内容 解决方案&#xff1a;使用 doLayout()方法 updated() {this.$nextTick(() > {this.$refs[inventorySumTable].doLayout();});},完整代码&#xff1a; // show-summary&#xff1a…

电子文件怎么盖章?

电子文件怎么盖章&#xff1f;电子文件盖章是数字化办公中常见的操作&#xff0c;包括盖电子公章和电子骑缝章。以下是针对这两种情况的详细步骤&#xff1a; 一、盖电子公章 方法一&#xff1a;使用专业软件 选择软件&#xff1a;选择一款专业的电子签名或PDF编辑软件&…

Bugku的web题目get,post

1.web基础$_GET http://114.67.175.224:17587/ OK明显的代码审计题目。 让我们看看代码&#xff0c;先get获取what参数变量&#xff0c;如果what变量‘flag’&#xff0c;输出flag。 该题为GET传参&#xff0c;可直接在url后面加参数 在url后加上?whatflag 即可获得flag 2…

速盾:移动端cdn和pc端cdn加速一样吗?

CDN&#xff08;Content Delivery Network&#xff09;是分布在不同地理位置的服务器集群&#xff0c;用于存储、传输和交付网络内容&#xff0c;旨在提高用户访问网站的速度和性能。移动端CDN和PC端CDN在原理上是相同的&#xff0c;都是通过将网站的静态内容缓存在离用户更近的…

科普文:科普文:springcloud之-Hystrix服务容错

Hystrix概念 Hystrix 服务容错保护 的概念和说明 这就是大名鼎鼎的&#xff1a;豪猪 豪猪的英文就是&#xff1a;Hystrix&#xff0c;国外一些大牛的程序员在给自己的架构起名字的时候&#xff0c;往往就这么特别。哪天咱们中国人自己也能写出些架构&#xff0c;咱们就按照中…

2024后端开发面试题总结

一、前言 上一篇离职贴发布之后仿佛登上了热门&#xff0c;就连曾经阿里的师兄都看到了我的分享&#xff0c;这波流量真是受宠若惊&#xff01; 回到正题&#xff0c;文章火之后&#xff0c;一些同学急切想要让我分享一下面试内容&#xff0c;回忆了几个晚上顺便总结一下&#…

【VS2019安装+QT配置】

【VS2019安装QT配置】 1. 前言2. 下载visual studio20193. visual studio2019安装4. 环境配置4.1 系统环境变量配置4.2 qt插件开发 5. Visual Studio导入QT项目6. 总结 1. 前言 前期安装了qt&#xff0c;发现creator编辑器并不好用&#xff0c;一点都不时髦。在李大师的指导下&…

MongoDB - 比较查询操作符$eq | 数组查询操作符 $eleMatch

文章目录 1. $eq 比较查询操作符1.1 基本类型字段1.2 嵌入式文档字段1.3 数组字段 2. $eleMatch 数组查询操作符2.1 基本类型数组字段2.2 基本类型数组字段2.3 嵌入式文档数组字段2.4 嵌入式文档数组字段 1. $eq 比较查询操作符 $eq 操作符匹配字段值等于指定值的文档。 db.c…

C++画蜡烛图

GPT-4o (OpenAI) 在 C 中绘制蜡烛图通常不像在高级语言&#xff08;如 Python&#xff09;中那么简单&#xff0c;因为 C 并没有内置的图形绘制库。然而&#xff0c;您可以使用一些第三方库来完成这项任务&#xff0c;比如使用 Qt 或者 SFML 等图形库。这里我们以 Qt 库为例&a…