Skip to main content

Crypto Guide

Encrypt and decrypt files, bytes, and strings using EFM's AES-256 (CBC mode) encryption.

Overview

EFM provides AES-256 CBC encryption, built on Unreal's own Core AES implementation, for:

  • Files (encrypt/decrypt on disk)
  • Byte arrays (in-memory)
  • Strings (in-memory)

Any string works as a key - it gets hashed into a proper 256-bit key internally. A random IV is generated on every call, so encrypting the same data twice never produces the same output.

Note: This is encryption only, there's no integrity check on the encrypted data, so it's meant for save games and local config rather than anything that needs tamper detection against a determined attacker.

File Encryption

Encrypt a File

EncryptFile(
GetGameSavedDirectory() + "save.dat", // Source
GetGameSavedDirectory() + "save.enc", // Destination (encrypted)
"MySecretKey123" // Encryption key
)

Decrypt a File

DecryptFile(
GetGameSavedDirectory() + "save.enc", // Source (encrypted)
GetGameSavedDirectory() + "save.dat", // Destination (decrypted)
"MySecretKey123" // Same key
)

Encrypt/Decrypt via UEFMFile

ReadFile(Dir, "save.dat") -> bSuccess, SaveFile
if bSuccess:
// Encrypt in-place
SaveFile.Encrypt("MySecretKey123")

// Later, decrypt
SaveFile.Decrypt("MySecretKey123")

String Encryption

Encrypt a String

Encrypted = ""
if EncryptString("SensitiveData", "MyKey", Encrypted):
// Store Encrypted somewhere
// Encrypted now contains garbled text

Decrypt a String

Decrypted = ""
if DecryptString(Encrypted, "MyKey", Decrypted):
// Decrypted now contains "SensitiveData"

Byte Array Encryption

Encrypt Bytes

EncryptedBytes = EncryptBytes(OriginalBytes, "MyKey")
// Write encrypted bytes to disk
WriteBytesToFile("data.enc", EncryptedBytes)

Decrypt Bytes

EncryptedBytes = ReadBytesFromFile("data.enc")
DecryptedBytes = DecryptBytes(EncryptedBytes, "MyKey")
// DecryptedBytes now contains the original data

Practical Example: Encrypted Save System

// Save game
function SaveGame(PlayerData):
JsonString = SerializeToJson(PlayerData)
Encrypted = ""
EncryptString(JsonString, "PlayerSaveKey2024", Encrypted)
AsyncWriteString(Self, GetGameSavedDirectory() + "save.enc", Encrypted, OnSaveComplete)

// Load game
function LoadGame():
AsyncReadFileAsString(Self, GetGameSavedDirectory() + "save.enc", OnReadComplete)
OnReadComplete(bSuccess, Content):
if bSuccess:
Decrypted = ""
if DecryptString(Content, "PlayerSaveKey2024", Decrypted):
PlayerData = ParseFromJson(Decrypted)
ApplyPlayerData(PlayerData)
else:
LogError("Failed to decrypt save file")
else:
LogError("Failed to read save file")

Key Management Tips

  1. Never hardcode keys in shipped builds - use a key derived from player-specific data
  2. Rotate keys periodically for sensitive data
  3. Store keys securely - consider using platform-specific secure storage
  4. Any key length works - it's hashed into a 256-bit AES key internally
  5. Test encryption/decryption round-trips to ensure data integrity