Decrypting Dead by Daylight CDN Content
November 23, 2024
Last Modified: May 16, 2025
Disclaimer
The information included in this post is for educational purposes only. Any material on this webpage may not be reproduced, retransmitted, or redisplayed other than for personal or educational use.
Introduction
A content delivery network (CDN) is a group of geographically distributed servers that speed up the delivery of web content by bringing it closer to where users are. Dead by Daylight serves client data from its private API through its CDN. Although client data can be intercepted by capturing Dead by Daylight's network traffic and passing the title screen, the response is encoded as a modified Base64-encoded string, adding layers of obfuscation to its contents.
Dead by Daylight CDN Content Structure
The Dead by Daylight client communicates with the game server through a REST API, with different endpoints utilizing distinct encoding methods. Content served from the CDN is prefixed with "DbdDAwAC", whereas save profiles are prefixed with "DbdDAgAC". The prefix "DbdDAQEB" indicates that the content is zlib-compressed.
Decryption Process
Content served from the CDN uses Base64 encoding, ASCII encoding, AES encryption, bit manipulation, and potentially zlib compression. The decryption process is carried out as follows:
1. Check if the content begins with a specific encryption prefix. Decryption cannot proceed if it does not.
2. Remove the prefix from the content to isolate the encrypted payload. Base64-decode the remaining payload to get the raw binary data.
3. Determine the length of the key ID buffer slice based on the length of the branch (in the case of Dead by Daylight, this is either "qa", "stage", "cert", "ptb", or "live"), extract that slice from the beginning of the raw payload, and transform the slice by incrementing each byte's value modulo 256.
4. Decode the key ID buffer into an ASCII string, replacing any "\u0001"
(Start of Heading) characters with ""
(empty strings). Then, use the resulting string to look up the required AES access key. You can use FModel to obtain the required AES access key, provided that you have both a mapping file and the AES key associated with the Dead by Daylight client. Supply FModel with the relevant mapping file and AES key, navigate to DeadbyDaylight > Config > DefaultGame.ini, and search "[/Script/S3Command.AccessKeys]". You will see the list of AES access keys below that section header. If you do not see "DefaultGame.ini" in the "Config" folder while using FModel, then you will need to export the "Config" folder's packages raw data to the output directory of your choice and open it from there.
5. Base64-decode the AES access key to retrieve the actual decryption key.
6. Extract the remaining part of the raw payload after the key ID buffer (hereafter referred to as the decoded buffer).
7. To process the decoded buffer, first create a new AES cipher object using the decrypted key from before and specifying the electronic codebook (ECB) mode. The cipher is then used to decrypt the decoded buffer.
8. Convert the decrypted buffer into a mutable byte array to allow for in-place modifications to the bytes.
9. Loop through the byte array such that bytes with non-zero values are adjusted by adding 1 (modulo 256) and then stored back into the byte array. For each non-zero byte, increment a "valid non-padding bytes" counter; this is used to determine how much of the data is valid and how much is padding. When a byte with value 0 is encountered, terminate the loop; this is where the padding ends.
10. After the loop, slice the byte array such that only the valid non-padding bytes are kept. Convert this slice back to a byte string and decode it into an ASCII string.
11. If the content was not zlib-compressed, then return it. Otherwise, proceed to step 12.
12. Since the content was zlib-compressed, remove the prefix from it to isolate the compressed payload. Base64-decode the remaining payload to get the raw binary data.
13. The first 4 bytes of the raw payload are interpreted as a little-endian integer, which specifies the expected size of the decompressed data. Decompress the remaining part of the raw payload (after the first 4 bytes).
14. Once the data is decompressed, decode it from UTF-16 to a string.
15. Return the content.
Instructions
The following is a list of instructions required to decrypt content transmitted through the Dead by Daylight CDN:
1. Visit https://www.python.org/downloads/ and left-click on the appropriate download link.
2. Head to the location of the completed download and run the Python Setup for whichever version of Python you downloaded. Ensure that you have "Add python.exe to PATH" checked. Left-click on "Install Now".
3. Once you have installed Python, open Windows PowerShell. Type the following into the terminal:
pip install pycryptodome
This will install the PyCryptodome Python package to your machine. You can verify that you have successfully installed it by typing the following into the terminal:
pip list
If you successfully followed the instructions, then you will see the "pycryptodome" package and the version of it that you installed in the list.
4. Visit this URL and left-click on the "Download raw file" icon. Save the Python script into the directory of your choice.
5. Head to the location of the completed download, right-click inside the directory, and left-click on "Open in Terminal".
6. After Windows PowerShell launches, type the following into the terminal:
python dbd_cdn_decryptor.py
7. You should now be prompted to either manually enter the encrypted data or load it from a file. Once the data is provided, you will be prompted to select a branch by entering its corresponding key and pressing the "Enter" key.
8. For example, to decrypt "contentSchedule.json" from this URL using the first input method, you would do the following in the terminal, pressing the "Enter" key after each step:
python dbd_cdn_decryptor.py
1: Enter encrypted data manually
2: Load encrypted data from a file
Select an input method: 1
Enter the encrypted data: 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
Select a branch (q: QA, s: Stage, c: Cert, p: PTB, l: live): l
9. After you do this, the Python script will return the decrypted data to your terminal.