Pak signing doesn't work on 4.27.2

The issue is quite simple. I’ve enabled pak signing in the project settings and my DefaultCrypto.ini looks like this:

[/Script/CryptoKeys.CryptoKeysSettings]
EncryptionKey=readcted
bEncryptPakIniFiles=True
bEncryptPakIndex=True
bEncryptUAssetFiles=False
bEncryptAllAssetFiles=False
SigningPublicExponent=redacted
SigningModulus=redacted
SigningPrivateExponent=redacted
bEnablePakSigning=True

When I build and packaged the project, I get a slew of .pak and their .sig files, so the files are obviously being signed in the packing process.

I’ve tried testing how this works by opening a random pak file, finding a random 2 somewhere and changing it to 1, effectively flipping a single bit, which should invalidate the signature of the pak file, with a low chance of corrupting the file. However, the game starts just fine.

I’ve then added a bunch of numbers at the same spot and got a following error:

Fatal error: [File:Unknown] [Line: 5182]
Corrupt pak index detected on pak file:
../../../Game/Content/Paks/pakchunk10-WindowsNoEditor.pak

This looks like I’ve corrupted the pak file by adding a bunch of numbers to it, making it unable to load, rather than refusing to load due to mismatching signature file.

So, why doesn’t any kind of tampering of any pak files prevent the game from loading?

EDIT: Solved, everything does work, you just have to react to the anything manually, see posts below.

I’ve looked into it further. I thought, maybe I changed some part of the pak file that was irrelevant and thus wasn’t triggering sign check.

I’ve looked into TmpPackaging folder with indices for pak files to find a specific asset that has several strings in it.

I’ve opened the pak file that contains it, found where it is stored within the pak file and change a single bit (this time 4 → 5, 100 → 101) that I know is within that asset. I started the game and the asset no longer works in the game, which means I really did break it in some way. The game did not detect I tampered with the pak file though.

What gives? How do I make it work?

Going further, I tried deleting the sig file for the same pak file and the asset in question was broke, despite pak being untouched. When I reverted the sig file, it started working again.

I’m even more confused now.

Okay, so there are mentions in the log of sig file not being found of sig mismatch if I tamper with the pak files.

There are two delegates that get triggered when something goes wrong:

This one when pak is tampered with:
DECLARE_MULTICAST_DELEGATE_OneParam(FPakChunkSignatureCheckFailedHandler, const FPakChunkSignatureCheckFailedData&);

This one when sig file is missing:
DECLARE_MULTICAST_DELEGATE_OneParam(FPakMasterSignatureTableCheckFailureHandler, const FString&);

These get called pretty early in the engine initialization process, so you can use something like this if you want make sure you’re delegates are hooked early enough to catch them:

SomeClass.h

static FDelayedAutoRegisterHelper _pakIntegrityChecker;

SomeClass.cpp

FDelayedAutoRegisterHelper SomeClass::_pakIntegrityChecker(EDelayedRegisterRunPhase::FileSystemReady, []()
{
	 
FPakPlatformFile::GetPakSigningFailureHandlerData().ChunkSignatureCheckFailedDelegate.AddLambda([](const FPakChunkSignatureCheckFailedData& data)
	{
		const FString message = FString::Printf(TEXT("Pak file or matching sig file integrity compromised: %s\nTry verifying the game files and starting the game again"), *data.PakFilename);
		FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(message));
		FGenericPlatformMisc::RequestExit(true);
	});

	FPakPlatformFile::GetPakSigningFailureHandlerData().MasterSignatureTableCheckFailedDelegate.AddLambda([](const FString& filename)
	{
		const FString message = FString::Printf(TEXT("Pak file or matching sig file integrity compromised: %s\nTry verifying the game files and starting the game again"), *filename);
		FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(message));
		FGenericPlatformMisc::RequestExit(true);
	});
});
1 Like