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
- Never hardcode keys in shipped builds - use a key derived from player-specific data
- Rotate keys periodically for sensitive data
- Store keys securely - consider using platform-specific secure storage
- Any key length works - it's hashed into a 256-bit AES key internally
- Test encryption/decryption round-trips to ensure data integrity