Fortnite replay files can be encrypted using AES encryption. The library automatically handles decryption when an encryption key is embedded in the replay file.
Epic Games encrypts certain replay files to protect sensitive player data. The encryption uses AES (Rijndael) with ECB mode and PKCS7 padding.What Gets Encrypted:
The ReplayInfo class contains encryption information read from the file header:
public class ReplayInfo{ public bool Encrypted { get; set; } // Is this replay encrypted? public byte[] EncryptionKey { get; set; } // AES decryption key}
From ReplayReader.cs:569-574, the library validates encryption status:
if (fileVersion >= ReplayVersionHistory.Encryption){ info.Encrypted = archive.ReadUInt32AsBoolean(); info.EncryptionKey = archive.ReadArray(archive.ReadByte);}if (!info.IsLive && info.Encrypted && (info.EncryptionKey.Length == 0)){ throw new InvalidReplayException( "Completed replay is marked encrypted but has no key!" );}
Replays marked as encrypted must have a valid encryption key in the header. If the key is missing, parsing will fail with InvalidReplayException.
The library automatically decrypts replay data when processing events and chunks. No special code is required:
var reader = new ReplayReader();var replay = reader.ReadReplay("encrypted.replay", ParseType.Minimal);// Data is automatically decryptedConsole.WriteLine($"Eliminations: {replay.Eliminations.Count}");Console.WriteLine($"Encrypted: {replay.Info.Encrypted}");
The Decrypt() method in FortniteReplayReader.cs:489-527 handles all decryption:
protected override Unreal.Core.BinaryReader Decrypt(FArchive archive, int size){ if (!this.Replay.Info.Encrypted) { // Not encrypted, return data as-is var decryptedReader = new Unreal.Core.BinaryReader( new MemoryStream(archive.ReadBytes(size)) ); decryptedReader.EngineNetworkVersion = Replay.Header.EngineNetworkVersion; decryptedReader.NetworkVersion = Replay.Header.NetworkVersion; decryptedReader.ReplayHeaderFlags = Replay.Header.Flags; decryptedReader.ReplayVersion = Replay.Info.FileVersion; return decryptedReader; } // Decrypt encrypted data var encryptedBytes = archive.ReadBytes(size); var key = this.Replay.Info.EncryptionKey; using RijndaelManaged rDel = new() { KeySize = (key.Length * 8), // Key size in bits Key = key, Mode = CipherMode.ECB, // Electronic Codebook mode Padding = PaddingMode.PKCS7 // PKCS7 padding }; using ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] decryptedArray = cTransform.TransformFinalBlock( encryptedBytes, 0, encryptedBytes.Length ); var decrypted = new Unreal.Core.BinaryReader(new MemoryStream(decryptedArray)); // Set network versions... return decrypted;}
Decryption happens transparently for both events (via ReadEvent()) and replay data chunks (via ReadReplayData()). The same Decrypt() method is used for both.
Fortnite replays use the following AES configuration:
Setting
Value
Description
Algorithm
Rijndael (AES)
Advanced Encryption Standard
Mode
ECB
Electronic Codebook
Padding
PKCS7
PKCS #7 padding scheme
Key Size
128/256 bits
Depends on key length
ECB mode is generally not recommended for encryption due to security concerns (identical plaintext blocks produce identical ciphertext blocks). However, this is the mode Epic Games uses for replay files.
Live (in-progress) replays cannot be encrypted. From ReplayReader.cs:582-586:
if (info.IsLive && info.Encrypted){ _logger?.LogError( "ReadReplayInfo: Replay is marked encrypted and but not yet marked as completed!" ); throw new InvalidReplayException( "Replay is marked encrypted and but not yet marked as completed!" );}
Only completed replays can be encrypted. Live replays that are still being recorded cannot have encryption applied.
Error:InvalidReplayException: Completed replay is marked encrypted but has no key!Cause: The replay file is marked as encrypted but doesn’t contain the decryption key in the header.Solution: This replay file is corrupted or was improperly saved. The encryption key should be embedded in the replay by the game when saving.
Live Replay Marked as Encrypted
Error:InvalidReplayException: Replay is marked encrypted and but not yet marked as completed!Cause: The replay file claims to be both live and encrypted, which is an invalid state.Solution: This indicates a corrupted or improperly formatted replay file. Wait for the replay to be fully written before parsing.
Decryption Fails Silently
Symptom: Events or data chunks appear empty or corrupted after parsingCause: The encryption key in the header may be incorrect or the data may be corrupted.Solution: Verify the replay file is complete and not corrupted. Enable debug logging to see decryption details:
var logger = LoggerFactory.Create(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Debug)).CreateLogger<ReplayReader>();var reader = new ReplayReader(logger: logger);
Do not rely on replay encryption for security-critical applications. The encryption key is stored in plaintext within the replay file itself, making it easily accessible.
Replay encryption is designed to:
✅ Prevent casual viewing/editing of replay files
✅ Deter simple hex editors and basic analysis tools
❌ NOT provide true security against determined attackers
❌ NOT protect sensitive data (keys are embedded in the file)
The encryption is primarily an obfuscation mechanism rather than a security measure.