Phasmophobia save files use a custom encryption format combining AES-CBC encryption with PBKDF2 key derivation. This page documents the binary format and JSON structure.
File Location
Windows
%USERPROFILE%\AppData\LocalLow\Kinetic Games\Phasmophobia\SaveFile.txt
Full path:
C:\Users\[Username]\AppData\LocalLow\Kinetic Games\Phasmophobia\SaveFile.txt
The save file is a binary file with the following structure:
┌─────────────────────┬─────────────────────────────┐
│ Initialization │ Encrypted JSON Data │
│ Vector (IV) │ (AES-CBC encrypted) │
│ 16 bytes │ Variable length │
└─────────────────────┴─────────────────────────────┘
Structure Breakdown
Bytes 0-15: Initialization Vector
Random 16-byte IV generated during encryption. Used as both the IV for AES and the salt for PBKDF2.
Bytes 16-end: Encrypted Data
AES-CBC encrypted JSON data with PKCS7 padding.
Encryption Algorithm
Parameters
AES (Advanced Encryption Standard)
CBC (Cipher Block Chaining)
Key Derivation (PBKDF2)
var key = new Rfc2898DeriveBytes (
password : "t36gref9u84y7f43g" , // Hard-coded secret
salt : iv , // The 16-byte IV
iterations : 100 , // Low iteration count
hashAlgorithm : HashAlgorithmName . SHA1
). GetBytes ( 16 );
"t36gref9u84y7f43g" - Hard-coded in Globals.Save_Secret
The 16-byte IV (same value used for AES-CBC)
100 iterations (relatively low for modern standards)
SHA1 (deprecated but still used by the game)
The encryption uses a hard-coded secret key, making all Phasmophobia save files vulnerable to decryption by anyone with this key.
Decryption Process
Extract IV
Read the first 16 bytes as the Initialization Vector. var iv = new byte [ 16 ];
Array . Copy ( data , iv , 16 );
Derive AES Key
Use PBKDF2 with the hard-coded secret and extracted IV. using var dbytes = new Rfc2898DeriveBytes (
"t36gref9u84y7f43g" ,
iv ,
100 ,
HashAlgorithmName . SHA1
);
var key = dbytes . GetBytes ( 16 );
Configure AES Decryptor
Set up AES with CBC mode and PKCS7 padding. using var aes = Aes . Create ();
aes . Mode = CipherMode . CBC ;
aes . Padding = PaddingMode . PKCS7 ;
aes . Key = key ;
aes . IV = iv ;
Decrypt Data
Decrypt bytes 16 onwards using the configured AES decryptor. using var decryptor = aes . CreateDecryptor ();
using var ms = new MemoryStream ( data , 16 , data . Length - 16 );
using var cs = new CryptoStream ( ms , decryptor , CryptoStreamMode . Read );
using var reader = new StreamReader ( cs , Encoding . UTF8 );
string json = reader . ReadToEnd ();
Encryption Process
Generate Random IV
Create a random 16-byte IV. byte [] iv = new byte [ 16 ];
using ( var rng = RandomNumberGenerator . Create ())
{
rng . GetBytes ( iv );
}
Derive AES Key
Use PBKDF2 with the hard-coded secret and generated IV. var key = new Rfc2898DeriveBytes (
"t36gref9u84y7f43g" ,
iv ,
100 ,
HashAlgorithmName . SHA1
). GetBytes ( 16 );
Encrypt JSON Data
Encrypt the JSON string using AES-CBC. using var aes = Aes . Create ();
aes . Mode = CipherMode . CBC ;
aes . Padding = PaddingMode . PKCS7 ;
aes . Key = key ;
aes . IV = iv ;
var ms = new MemoryStream ();
using ( var enc = aes . CreateEncryptor ())
using ( var cs = new CryptoStream ( ms , enc , CryptoStreamMode . Write ))
using ( var writer = new StreamWriter ( cs , Encoding . UTF8 ))
{
writer . Write ( jsonData );
}
byte [] encryptedData = ms . ToArray ();
Prepend IV
Combine IV and encrypted data into final output. byte [] result = new byte [ iv . Length + encryptedData . Length ];
Buffer . BlockCopy ( iv , 0 , result , 0 , iv . Length );
Buffer . BlockCopy ( encryptedData , 0 , result , iv . Length , encryptedData . Length );
JSON Structure
Once decrypted, the save file contains JSON with this general structure:
{
"PropertyName" : {
"__type" : "int" ,
"value" : 100
},
"PlayersMoney" : {
"__type" : "int" ,
"value" : 50000
},
"Experience" : {
"__type" : "int" ,
"value" : 25000
},
"TierTwoUnlockOwned" : {
"__type" : "bool" ,
"value" : false
},
"TierThreeUnlockOwned" : {
"__type" : "bool" ,
"value" : false
},
"EMFReaderInventory" : {
"__type" : "int" ,
"value" : 10
},
"FlashlightInventory" : {
"__type" : "int" ,
"value" : 5
}
}
Each property follows this structure:
{
"PropertyName" : {
"__type" : "<type>" ,
"value" : <value>
}
}
Data type: "int", "bool", "string", etc.
The actual value (type matches __type).
Key Properties
PlayersMoney Player’s in-game currency (integer)
Experience Player’s XP points (integer)
TierTwoUnlockOwned Tier 2 items unlocked (boolean)
TierThreeUnlockOwned Tier 3 items unlocked (boolean)
[Item]Inventory Quantity of each item type (integer)
Example: Complete Workflow
using PhasmoDecrypt ;
// 1. Read encrypted save file
string savePath = Path . Combine (
Environment . GetFolderPath ( Environment . SpecialFolder . UserProfile ),
"AppData" , "LocalLow" , "Kinetic Games" , "Phasmophobia" , "SaveFile.txt"
);
byte [] encryptedData = File . ReadAllBytes ( savePath );
// 2. Decrypt to JSON
var crypter = new Crypter ();
string json = crypter . Decrypt ( encryptedData );
// 3. Modify JSON
EditJson . UnlockAllTier3 ( json );
EditJson . EditMoney ( Globals . DecryptedText , 999999 );
EditJson . InfinityXp ( Globals . DecryptedText , 1000000 );
// 4. Encrypt modified JSON
byte [] newEncryptedData = crypter . EncryptData ( Globals . DecryptedText );
// 5. Save (backup original first!)
File . Copy ( savePath , savePath + ".backup" , true );
File . WriteAllBytes ( savePath , newEncryptedData );
Always backup the original save file before modifying it. Corrupted save files cannot be recovered.
Security Considerations
The encryption key "t36gref9u84y7f43g" is hard-coded in the game, making all save files equally vulnerable.
PBKDF2 uses only 100 iterations, which is far below modern recommendations (100,000+).
Deprecated Hash Algorithm
SHA1 is cryptographically broken and should not be used for new applications.
Using the same IV as both the AES IV and PBKDF2 salt is unconventional but not necessarily insecure.
This encryption is designed for save file integrity, not security. It prevents casual editing but is trivial to bypass with the known secret key.
Source References
Encryption/Decryption: /workspace/source/Classes/Crypter.cs
Secret Key: /workspace/source/Classes/Globals.cs:7
File Handling: /workspace/source/Program.cs:88-99