summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromg <root@frp3.fr>2026-08-21 11:52:18 +0000
committeromg <root@frp3.fr>2026-08-21 11:52:18 +0000
commit3cdfe0da332d13f0d9bf62512f2a31b1995d1816 (patch)
treea46970370c6acd1bacffd515184e2681c7e17ff2
parent545859c0c296a6cdb05f18d4a580da02335266aa (diff)
Added GodotSecure supportHEADmain
-rw-r--r--Godot.Secure.AES-256.Release-v4_v4.6.x.-.Latest.py545
-rw-r--r--Log-2026-08-21_11-43-23-973182-Godot-Secure-AES.txt8
-rw-r--r--Log-2026-08-21_11-43-45-886657-Godot-Secure-AES.txt8
-rw-r--r--Log-2026-08-21_11-44-08-879220-Godot-Secure-AES.txt8
-rw-r--r--Log-2026-08-21_11-44-50-030431-Godot-Secure-AES.txt8
-rw-r--r--Log-2026-08-21_11-45-07-074435-Godot-Secure-AES.txt12
-rw-r--r--Log-2026-08-21_11-45-37-736396-Godot-Secure-AES.txt68
-rw-r--r--core/crypto/security_token.h11
-rwxr-xr-xcore/io/file_access_encrypted.cpp46
-rwxr-xr-xcore/io/file_access_encrypted.h2
-rwxr-xr-xcore/io/file_access_pack.h2
-rwxr-xr-xversion.py2
12 files changed, 703 insertions, 17 deletions
diff --git a/Godot.Secure.AES-256.Release-v4_v4.6.x.-.Latest.py b/Godot.Secure.AES-256.Release-v4_v4.6.x.-.Latest.py
new file mode 100644
index 0000000000..e1b3b87114
--- /dev/null
+++ b/Godot.Secure.AES-256.Release-v4_v4.6.x.-.Latest.py
@@ -0,0 +1,545 @@
+import os
+import sys
+import random
+import string
+import binascii
+import secrets
+import datetime
+
+class LogColors:
+ HEADER = '\033[95m'
+ OKBLUE = '\033[94m'
+ OKGREEN = '\033[92m'
+ WARNING = '\033[93m'
+ FAIL = '\033[91m'
+ ENDC = '\033[0m'
+ BOLD = '\033[1m'
+ UNDERLINE = '\033[4m'
+
+def generate_random_tag(length=4):
+ return ''.join(random.choices(string.ascii_uppercase, k=length))
+
+def generate_random_token(length=32):
+ return bytes([random.randint(0, 255) for _ in range(length)])
+
+def hex_to_bytes(hex_string: str) -> bytes:
+ return bytes.fromhex(hex_string)
+
+def generate_magic_header(tag: str, endian='little') -> str:
+ if len(tag) != 4:
+ raise ValueError("Tag must be exactly 4 characters.")
+
+ if endian == 'little':
+ tag = tag[::-1] # Reverse for little-endian
+
+ hex_value = "0x" + ''.join(f"{ord(c):02X}" for c in tag)
+ return hex_value
+
+def build_random_key_derivation():
+ operands = ["key_ptr[i]", "Security::TOKEN[i]"]
+
+ base_ops = [
+ "({a} ^ {b})",
+ "({a} + {b})",
+ "({a} | {b})",
+ "({a} & {b})",
+ "(({a} << {shift}) | ({a} >> {rshift}))",
+ "(({a} ^ {b}) + {const})",
+ "(({a} + {b}) ^ {const})",
+ ]
+
+ chain_ops = [
+ "({expr} ^ {value})",
+ "({expr} + {value})",
+ "({expr} | {value})",
+ "(({expr} << {shift}) | ({expr} >> {rshift}))",
+ "(({expr} ^ {value}) + {const})",
+ "(({expr} + {value}) ^ {const})",
+ ]
+
+ def rotation():
+ shift = secrets.randbelow(7) + 1
+ return shift, 8 - shift
+
+ def rand_const():
+ return secrets.randbelow(255) + 1 # never zero
+
+ layers = secrets.randbelow(5) + 2
+
+ a = secrets.choice(operands)
+ b = operands[1] if a == operands[0] else operands[0]
+ shift, rshift = rotation()
+
+ expression = secrets.choice(base_ops).format(a=a,b=b,shift=shift,rshift=rshift,const=rand_const())
+
+ for _ in range(layers - 1):
+ shift, rshift = rotation()
+ value = secrets.choice(operands)
+
+ # never allow identical cancellation
+ if value == expression:
+ value = secrets.choice(operands)
+
+ expression = secrets.choice(chain_ops).format(expr=expression,value=value,shift=shift,rshift=rshift,const=rand_const())
+
+ return f"token_key.write[i] = (uint8_t)({expression});"
+
+def save_log(message):
+ if not str(message).find("\033[") > 0:
+ with open(logFileName,"a", encoding="utf-8") as logf: logf.write(f"{message}\n")
+ return message
+
+def print_success(message):
+ save_log(f" [✓] {message}")
+ print(f"{LogColors.OKGREEN} ✓{LogColors.ENDC} {message}")
+
+def print_error(message):
+ save_log(f" [✗] {message}\n")
+ print(f"{LogColors.FAIL} ✗{LogColors.ENDC} {message}")
+
+def print_info(message):
+ save_log(f"\n[INFO] - {message}")
+ print(f"\n{LogColors.OKBLUE} ℹ {LogColors.ENDC} {message}")
+
+def print_operation(message):
+ save_log(f" [=>] {message}")
+ print(f"{LogColors.HEADER} =>{LogColors.ENDC} {message}")
+
+def print_warning(message):
+ save_log(f"\n[WARN] - {message}")
+ print(f"\n{LogColors.WARNING} ⚠ {LogColors.ENDC} {message}")
+
+
+# Generate unique identifiers
+global godot_root
+global encKey
+
+baseTag = generate_random_tag()
+encTag = generate_random_tag()
+security_token = generate_random_token()
+token_hex = binascii.hexlify(security_token).decode('utf-8')
+token_c_array = ', '.join([f'0x{b:02X}' for b in security_token])
+baseHeader = generate_magic_header(baseTag)
+encHeader = generate_magic_header(encTag)
+key_derivation_algorithm = "token_key.write[i] = key_ptr[i] ^ Security::TOKEN[i];"
+
+fileCreated = True
+backup_path = None
+current_dt = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S-%f")
+logFileName = f"Log-{current_dt}-Godot-Secure-AES.txt"
+
+
+# Start Script Startup Operations
+if len(sys.argv) == 1:
+ # No argument provided, use current directory
+ godot_root = os.getcwd()
+ print("\nNo directory specified. Using current directory as Godot Source Root.")
+elif len(sys.argv) == 2:
+ # One argument provided, use it as Godot root
+ godot_root = sys.argv[1]
+else:
+ # Too many arguments provided
+ print("\nUsage: python Godot_Secure.py <godot_source_root>")
+ try:
+ exit = input("\nPress Enter key to exit...")
+ except EOFError:
+ pass
+ sys.exit(1)
+
+
+# Log File Creation
+with open(logFileName, "w", encoding="utf-8") as logf: logf.write(f"Created On - {current_dt}\nThis is Godot-Secure Log file, SAVE IT to secure place for later getting values.\n\n")
+
+# Check for required Godot source components
+core_dir = os.path.join(godot_root, "core")
+sconstruct_file = os.path.join(godot_root, "SConstruct")
+
+# Get Current Encryption Key From Enviroment
+try:
+ encKey = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
+except:
+ encKey = "Can't Fetch Your Enviroment Variable \"SCRIPT_AES256_ENCRYPTION_KEY\""
+
+if not (os.path.isdir(core_dir) and os.path.isfile(sconstruct_file)):
+ log = save_log("Error: No valid Godot Source Detected in the Specified Directory.")
+ print(f"{LogColors.FAIL}{log}{LogColors.ENDC}")
+ try:
+ exit = input("\nPress Enter key to exit...")
+ except EOFError:
+ pass
+ sys.exit(1)
+
+print(save_log(f"\nUsing Godot Source Root: {godot_root}"))
+confirm = input(f"\n\n ⚠ {LogColors.WARNING}Start Godot Secure Operations on Godot Source Root {LogColors.ENDC}{LogColors.FAIL}(y/n)?{LogColors.ENDC}: ").strip().lower()
+if not (confirm == 'y' or confirm == 'yes'):
+ print(save_log("Closing Setup..."))
+ try:
+ exit = input("\nPress Enter key to exit...")
+ except EOFError:
+ pass
+ sys.exit(1)
+
+save_log(f"Start Godot Secure Operations on Godot Source Root (y/n)?: {confirm}")
+
+confirm = input(f"\n\n ℹ {LogColors.OKBLUE}Use Custom Headers {LogColors.ENDC}{LogColors.FAIL}(y/n)?{LogColors.ENDC}: ").strip().lower()
+save_log(f"\n[INFO] - Use Custom Headers (y/n)?: {confirm}")
+if (confirm == 'y' or confirm == 'yes'):
+ baseTag = input(" Enter Custom Magic Header (e.g. GDPC): ").upper()
+ baseHeader = generate_magic_header(baseTag)
+ encTag = input(" Enter Custom Encrypted Magic Header (e.g. GDEC): ").upper()
+ encHeader = generate_magic_header(encTag)
+ save_log(f" Enter Custom Magic Header (e.g. GDPC): {baseTag}\n Enter Custom Encrypted Magic Header (e.g. GDEC): {encTag}")
+
+confirm = input(f"\n\n ℹ {LogColors.OKBLUE}Use Custom Token {LogColors.ENDC}{LogColors.FAIL}(y/n)?{LogColors.ENDC}: ").strip().lower()
+save_log(f"\n[INFO] - Use Custom Token (y/n)?: {confirm}")
+if (confirm == 'y' or confirm == 'yes'):
+ token_hex = str(input(" Enter Custom Security Token: ")).lower()
+ security_token = hex_to_bytes(token_hex)
+ token_c_array = ', '.join([f'0x{b:02X}' for b in security_token])
+ save_log(f" Enter Custom Security Token: {token_hex}")
+
+confirm = input(f"\n\n ℹ {LogColors.OKBLUE}Use Advanced Key Derivation {LogColors.ENDC}{LogColors.FAIL}(y/n)?{LogColors.ENDC}: ").strip().lower()
+save_log(f"\n[INFO] - Use Advanced Key Derivation (y/n)?: {confirm}")
+if (confirm == 'y' or confirm == 'yes'):
+ key_derivation_algorithm = build_random_key_derivation()
+ save_log(f" Generated Advanced Key Derivation Algorithm:\n {key_derivation_algorithm}")
+
+# Modifications to be made in source
+MODIFICATIONS = [
+ #Pre -Steps:
+ {
+ "file": "version.py",
+ "operations": [
+ {
+ "type": "replace_line",
+ "description": "Modify Godot title To add Godot Secure",
+ "find": "name = \"Godot Engine\"",
+ "replace": "name = \"Godot Engine (With Godot Secure)\""
+ }
+ ]
+ },
+
+ {
+ "file": "editor/export/project_export.cpp",
+ "operations": [
+ {
+ "type": "replace_line",
+ "description": "Modify Godot export popup title To add Godot Secure",
+ "find": "set_title(TTR(\"Export\"));",
+ "replace": "set_title(TTR(\"Export With Godot Secure (AES-256)\"));"
+ }
+ ]
+ },
+
+ # Step 0: Create security token header
+ {
+ "file": "core/crypto/security_token.h",
+ "operations": [
+ {
+ "type": "create_file",
+ "description": "Create security token header",
+ "content": [
+ "#ifndef SECURITY_TOKEN_H",
+ "#define SECURITY_TOKEN_H",
+ "",
+ "#include \"core/typedefs.h\"",
+ "",
+ "namespace Security {",
+ f" //Security Token: {token_hex}",
+ f" static const uint8_t TOKEN[32] = {{ {token_c_array} }};",
+ "};",
+ "",
+ "#endif // SECURITY_TOKEN_H"
+ ]
+ }
+ ]
+ },
+ # Step 1: Magic Header Modification (Packed)
+ {
+ "file": "core/io/file_access_pack.h",
+ "operations": [
+ {
+ "type": "replace_line",
+ "description": "Modify Packed File Header Magic",
+ "find": "#define PACK_HEADER_MAGIC 0x43504447",
+ "replace": f"#define PACK_HEADER_MAGIC {baseHeader} // Generated Tag: \"{baseTag}\""
+ }
+ ]
+ },
+ # Step 2: Magic Header Modification (Encrypted)
+ {
+ "file": "core/io/file_access_encrypted.h",
+ "operations": [
+ {
+ "type": "replace_line",
+ "description": "Modify Encrypted File Header Magic",
+ "find": "#define ENCRYPTED_HEADER_MAGIC 0x43454447",
+ "replace": f"#define ENCRYPTED_HEADER_MAGIC {encHeader} // Generated Tag: \"{encTag}\""
+ }
+ ]
+ },
+ # Step 3: Modify AES Decryption + Token Integration
+ {
+ "file": "core/io/file_access_encrypted.cpp",
+ "operations": [
+ {
+ "type": "insert_after",
+ "description": "Include security token header",
+ "find": "#include \"file_access_encrypted.h\"",
+ "replace": "#include \"core/crypto/security_token.h\""
+ },
+ {
+ "type": "replace_block",
+ "description": "Add token obfuscation for decryption",
+ "find": [
+ "{",
+ "CryptoCore::AESContext ctx;",
+ "",
+ "ctx.set_encode_key(key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!",
+ "ctx.decrypt_cfb(ds, iv.ptrw(), data.ptrw(), data.ptrw());",
+ "}"
+ ],
+ "replace": [
+ "{",
+ "CryptoCore::AESContext ctx;",
+ "",
+ " // Apply security token to key",
+ " Vector<uint8_t> token_key;",
+ " token_key.resize(32);",
+ " const uint8_t *key_ptr = key.ptr();",
+ " for (int i = 0; i < 32; i++) {",
+ f" {key_derivation_algorithm}",
+ " }",
+ "",
+ " ctx.set_encode_key(token_key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!",
+ " ctx.decrypt_cfb(ds, iv.ptrw(), data.ptrw(), data.ptrw());",
+ "}"
+ ]
+ }
+ ]
+ },
+ # Step 4: Modify AES Encryption + Token Integration
+ {
+ "file": "core/io/file_access_encrypted.cpp",
+ "operations": [
+ {
+ "type": "replace_block",
+ "description": "Add token obfuscation for encryption",
+ "find": [
+ "CryptoCore::AESContext ctx;",
+ "ctx.set_encode_key(key.ptrw(), 256);",
+ "",
+ "if (use_magic) {",
+ " file->store_32(ENCRYPTED_HEADER_MAGIC);",
+ "}",
+ "",
+ "file->store_buffer(hash, 16);",
+ "file->store_64(data.size());",
+ "file->store_buffer(iv.ptr(), 16);",
+ "",
+ "ctx.encrypt_cfb(len, iv.ptrw(), compressed.ptr(), compressed.ptr());"
+ ],
+ "replace": [
+ "CryptoCore::AESContext ctx;",
+ "",
+ " // Apply security token to key",
+ " Vector<uint8_t> token_key;",
+ " token_key.resize(32);",
+ " const uint8_t *key_ptr = key.ptr();",
+ " for (int i = 0; i < 32; i++) {",
+ f" {key_derivation_algorithm}",
+ " }",
+ "",
+ " ctx.set_encode_key(token_key.ptrw(), 256);",
+ "",
+ "if (use_magic) {",
+ "file->store_32(ENCRYPTED_HEADER_MAGIC);",
+ "}",
+ "",
+ "file->store_buffer(hash, 16);",
+ "file->store_64(data.size());",
+ "file->store_buffer(iv.ptr(), 16);",
+ "",
+ "ctx.encrypt_cfb(len, iv.ptrw(), compressed.ptr(), compressed.ptr());"
+ ]
+ }
+ ]
+ }
+]
+
+def apply_modifications(root_dir):
+ print_info(f"Generated PACK_HEADER_MAGIC : {baseHeader} //Tag : {baseTag}")
+ print_info(f"Generated ENCRYPTED_HEADER_MAGIC : {encHeader} //Tag : {encTag}")
+ print_info(f"Security Token: {token_hex}")
+
+ step = 0
+ for mod in MODIFICATIONS:
+ file_path = os.path.join(root_dir, mod["file"])
+ step += 1
+
+ # Handle file creation separately
+ if any(op.get("type") == "create_file" for op in mod["operations"]):
+ print_info(f"Step {step} (Creating: {file_path}):")
+ for op in mod["operations"]:
+ if op["type"] == "create_file":
+ print_operation(f"Operation: {op['description']}")
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
+
+ if os.path.exists(file_path):
+ print_warning(f"File already exists: {file_path}")
+ choice = input(" Do you want to overwrite it? (y/n): ").strip().lower()
+ if not (choice == 'y' or choice == 'yes'):
+ global fileCreated
+ print_operation("Skipping file creation.")
+ fileCreated = False
+ continue
+
+ # Backup existing file
+ global backup_path
+ backup_path = file_path + ".backup"
+ try:
+ os.replace(file_path, backup_path)
+ print_operation(f"Backup created at: {backup_path}")
+ except Exception as e:
+ print_error(f"Failed to create backup: {e}")
+ print_operation("Skipping file creation.")
+ fileCreated = False
+ continue
+
+ try:
+ with open(file_path, "w") as f:
+ content = op["content"]
+ if isinstance(content, list):
+ content = "\n".join(content)
+ f.write(content)
+ print_success(f"File created: {file_path}")
+ except Exception as e:
+ print_error(f"Failed to write file: {e}")
+ continue
+
+
+ # Handle file modifications
+ if not os.path.exists(file_path):
+ print_error(f"File not found: {file_path}")
+ continue
+
+ print_info(f"Step {step} (Processing: {file_path}):")
+
+ with open(file_path, "r") as f:
+ lines = f.readlines()
+
+ modified = False
+ for op in mod["operations"]:
+ op_type = op["type"]
+ description = op.get("description", "")
+ print_operation(f"Operation: {description}. (Type: {op_type})")
+
+ if op_type == "replace_line":
+ find = op["find"].strip()
+ replace = op["replace"] + "\n"
+ found = False
+
+ for i in range(len(lines)):
+ if lines[i].strip() == find:
+ lines[i] = replace
+ print_success(f"Line replaced at line {i+1}")
+ found = True
+ modified = True
+ break
+
+ if not found:
+ print_error(f"Target line not found: {find}")
+
+ elif op_type == "replace_block":
+ find_lines = [ln.strip() for ln in op["find"]]
+ replace_lines = [ln + "\n" for ln in op["replace"]]
+ block_found = False
+
+ for i in range(len(lines) - len(find_lines) + 1):
+ match = True
+ for j in range(len(find_lines)):
+ if lines[i + j].strip() != find_lines[j]:
+ match = False
+ break
+ if match:
+ lines[i:i + len(find_lines)] = replace_lines
+ print_success(f"Block replaced starting at line {i+1}")
+ modified = True
+ block_found = True
+ break
+
+ if not block_found:
+ print_error("Target block not found")
+
+ elif op_type == "insert_after":
+ find = op["find"].strip()
+ replace_lines = [ln + "\n" for ln in op["replace"]] if isinstance(op["replace"], list) else [op["replace"] + "\n"]
+ found = False
+
+ for i in range(len(lines)):
+ if lines[i].strip() == find:
+ # Check if replacement already exists
+ already_present = True
+ for j, rep_line in enumerate(replace_lines):
+ if i + 1 + j >= len(lines) or lines[i + 1 + j] != rep_line:
+ already_present = False
+ break
+
+ if not already_present:
+ lines[i+1:i+1] = replace_lines
+ print_success(f"Inserted after line {i+1}")
+ modified = True
+ else:
+ print_success("Content already present, skipping insertion")
+ found = True
+ break
+
+ if not found:
+ print_error(f"Insertion point not found: {find}")
+
+ elif op_type == "append":
+ replace_lines = [ln + "\n" for ln in op["replace"]]
+ already_present = False
+
+ # Check if the ending lines match
+ if len(lines) >= len(replace_lines):
+ already_present = all(
+ lines[-len(replace_lines) + i] == replace_lines[i]
+ for i in range(len(replace_lines))
+ )
+
+ if not already_present:
+ lines.extend(replace_lines)
+ print_success("Appended to end of file")
+ modified = True
+ else:
+ print_success("Content already present at end, skipping append")
+
+ if modified:
+ with open(file_path, "w") as f:
+ f.writelines(lines)
+ print_success(f"File updated: {file_path}")
+ else:
+ print_warning(f"No changes made to file (Step {step})")
+
+if __name__ == "__main__":
+ log = save_log("\n=== Applying Enhanced AES Encryption For Godot ===")
+ print(f"\n\n{LogColors.HEADER}{log}{LogColors.ENDC}")
+ apply_modifications(godot_root)
+ print(f"\n{LogColors.HEADER}=== Operation Complete (View Logs For Info) ==={LogColors.ENDC}\n")
+ if fileCreated == True:
+ print(f"{LogColors.BOLD} Security Token:{LogColors.ENDC} {token_hex}\n")
+ print(f"{LogColors.WARNING} Encryption Key: {LogColors.FAIL}{encKey}{LogColors.ENDC}")
+ print_warning(f"{LogColors.WARNING} Security Token and Encryption Key are different. Use {LogColors.FAIL}\"Encryption Key\"{LogColors.WARNING} During Export!{LogColors.ENDC}")
+ print_success(f"{LogColors.OKGREEN} Build is now Cryptographically Unique{LogColors.ENDC}")
+ save_log(f"\nSecurity Token: {token_hex}\nEncryption Key: {encKey}")
+ save_log(f"\n[WARN] - Security Token and Encryption Key are different. Use Encryption Key During Export!")
+ if not (backup_path == None):
+ save_log(f"\n[INFO] - Old Key Backup Created at: {backup_path}")
+ print_info(f"{LogColors.OKGREEN} Old Key Backup Created at: {LogColors.ENDC}{LogColors.BOLD}{backup_path}{LogColors.ENDC}\n")
+
+ try:
+ exit = input("\nPress Enter key to exit...")
+ except EOFError:
+ pass
+ sys.exit(1)
diff --git a/Log-2026-08-21_11-43-23-973182-Godot-Secure-AES.txt b/Log-2026-08-21_11-43-23-973182-Godot-Secure-AES.txt
new file mode 100644
index 0000000000..c6d6bc9862
--- /dev/null
+++ b/Log-2026-08-21_11-43-23-973182-Godot-Secure-AES.txt
@@ -0,0 +1,8 @@
+Created On - 2026-08-21_11-43-23-973182
+This is Godot-Secure Log file, SAVE IT to secure place for later getting values.
+
+
+Using Godot Source Root: /var/lib/git/godot
+Start Godot Secure Operations on Godot Source Root (y/n)?: y
+
+[INFO] - Use Custom Headers (y/n)?: y
diff --git a/Log-2026-08-21_11-43-45-886657-Godot-Secure-AES.txt b/Log-2026-08-21_11-43-45-886657-Godot-Secure-AES.txt
new file mode 100644
index 0000000000..567d56a226
--- /dev/null
+++ b/Log-2026-08-21_11-43-45-886657-Godot-Secure-AES.txt
@@ -0,0 +1,8 @@
+Created On - 2026-08-21_11-43-45-886657
+This is Godot-Secure Log file, SAVE IT to secure place for later getting values.
+
+
+Using Godot Source Root: /var/lib/git/godot
+Start Godot Secure Operations on Godot Source Root (y/n)?: y
+
+[INFO] - Use Custom Headers (y/n)?: n
diff --git a/Log-2026-08-21_11-44-08-879220-Godot-Secure-AES.txt b/Log-2026-08-21_11-44-08-879220-Godot-Secure-AES.txt
new file mode 100644
index 0000000000..979554692d
--- /dev/null
+++ b/Log-2026-08-21_11-44-08-879220-Godot-Secure-AES.txt
@@ -0,0 +1,8 @@
+Created On - 2026-08-21_11-44-08-879220
+This is Godot-Secure Log file, SAVE IT to secure place for later getting values.
+
+
+Using Godot Source Root: /var/lib/git/godot
+Start Godot Secure Operations on Godot Source Root (y/n)?: y
+
+[INFO] - Use Custom Headers (y/n)?: y
diff --git a/Log-2026-08-21_11-44-50-030431-Godot-Secure-AES.txt b/Log-2026-08-21_11-44-50-030431-Godot-Secure-AES.txt
new file mode 100644
index 0000000000..ae38d87766
--- /dev/null
+++ b/Log-2026-08-21_11-44-50-030431-Godot-Secure-AES.txt
@@ -0,0 +1,8 @@
+Created On - 2026-08-21_11-44-50-030431
+This is Godot-Secure Log file, SAVE IT to secure place for later getting values.
+
+
+Using Godot Source Root: /var/lib/git/godot
+Start Godot Secure Operations on Godot Source Root (y/n)?: y
+
+[INFO] - Use Custom Headers (y/n)?: y
diff --git a/Log-2026-08-21_11-45-07-074435-Godot-Secure-AES.txt b/Log-2026-08-21_11-45-07-074435-Godot-Secure-AES.txt
new file mode 100644
index 0000000000..1be498ffa7
--- /dev/null
+++ b/Log-2026-08-21_11-45-07-074435-Godot-Secure-AES.txt
@@ -0,0 +1,12 @@
+Created On - 2026-08-21_11-45-07-074435
+This is Godot-Secure Log file, SAVE IT to secure place for later getting values.
+
+
+Using Godot Source Root: /var/lib/git/godot
+Start Godot Secure Operations on Godot Source Root (y/n)?: y
+
+[INFO] - Use Custom Headers (y/n)?: y
+ Enter Custom Magic Header (e.g. GDPC): PJEF
+ Enter Custom Encrypted Magic Header (e.g. GDEC): BHEQ
+
+[INFO] - Use Custom Token (y/n)?: y
diff --git a/Log-2026-08-21_11-45-37-736396-Godot-Secure-AES.txt b/Log-2026-08-21_11-45-37-736396-Godot-Secure-AES.txt
new file mode 100644
index 0000000000..b0cf0b9f28
--- /dev/null
+++ b/Log-2026-08-21_11-45-37-736396-Godot-Secure-AES.txt
@@ -0,0 +1,68 @@
+Created On - 2026-08-21_11-45-37-736396
+This is Godot-Secure Log file, SAVE IT to secure place for later getting values.
+
+
+Using Godot Source Root: /var/lib/git/godot
+Start Godot Secure Operations on Godot Source Root (y/n)?: y
+
+[INFO] - Use Custom Headers (y/n)?: y
+ Enter Custom Magic Header (e.g. GDPC): PJEF
+ Enter Custom Encrypted Magic Header (e.g. GDEC): BHEQ
+
+[INFO] - Use Custom Token (y/n)?: y
+ Enter Custom Security Token: 762834
+
+[INFO] - Use Advanced Key Derivation (y/n)?: y
+ Generated Advanced Key Derivation Algorithm:
+ token_key.write[i] = (uint8_t)(((((((((Security::TOKEN[i] ^ key_ptr[i]) + key_ptr[i]) ^ Security::TOKEN[i]) + 219) ^ key_ptr[i]) + 135) ^ key_ptr[i]) + 121));
+
+=== Applying Enhanced AES Encryption For Godot ===
+
+[INFO] - Generated PACK_HEADER_MAGIC : 0x46454A50 //Tag : PJEF
+
+[INFO] - Generated ENCRYPTED_HEADER_MAGIC : 0x51454842 //Tag : BHEQ
+
+[INFO] - Security Token: 762834
+
+[INFO] - Step 1 (Processing: /var/lib/git/godot/version.py):
+ [=>] Operation: Modify Godot title To add Godot Secure. (Type: replace_line)
+ [✓] Line replaced at line 2
+ [✓] File updated: /var/lib/git/godot/version.py
+
+[INFO] - Step 2 (Processing: /var/lib/git/godot/editor/export/project_export.cpp):
+ [=>] Operation: Modify Godot export popup title To add Godot Secure. (Type: replace_line)
+ [✗] Target line not found: set_title(TTR("Export"));
+
+
+[WARN] - No changes made to file (Step 2)
+
+[INFO] - Step 3 (Creating: /var/lib/git/godot/core/crypto/security_token.h):
+ [=>] Operation: Create security token header
+ [✓] File created: /var/lib/git/godot/core/crypto/security_token.h
+
+[INFO] - Step 4 (Processing: /var/lib/git/godot/core/io/file_access_pack.h):
+ [=>] Operation: Modify Packed File Header Magic. (Type: replace_line)
+ [✓] Line replaced at line 41
+ [✓] File updated: /var/lib/git/godot/core/io/file_access_pack.h
+
+[INFO] - Step 5 (Processing: /var/lib/git/godot/core/io/file_access_encrypted.h):
+ [=>] Operation: Modify Encrypted File Header Magic. (Type: replace_line)
+ [✓] Line replaced at line 36
+ [✓] File updated: /var/lib/git/godot/core/io/file_access_encrypted.h
+
+[INFO] - Step 6 (Processing: /var/lib/git/godot/core/io/file_access_encrypted.cpp):
+ [=>] Operation: Include security token header. (Type: insert_after)
+ [✓] Inserted after line 31
+ [=>] Operation: Add token obfuscation for decryption. (Type: replace_block)
+ [✓] Block replaced starting at line 102
+ [✓] File updated: /var/lib/git/godot/core/io/file_access_encrypted.cpp
+
+[INFO] - Step 7 (Processing: /var/lib/git/godot/core/io/file_access_encrypted.cpp):
+ [=>] Operation: Add token obfuscation for encryption. (Type: replace_block)
+ [✓] Block replaced starting at line 165
+ [✓] File updated: /var/lib/git/godot/core/io/file_access_encrypted.cpp
+
+Security Token: 762834
+Encryption Key: f2d2fe537ce75c61062dadaf3fa6647b494cba92623661b12485944d02598aa7
+
+[WARN] - Security Token and Encryption Key are different. Use Encryption Key During Export!
diff --git a/core/crypto/security_token.h b/core/crypto/security_token.h
new file mode 100644
index 0000000000..a08aad95bf
--- /dev/null
+++ b/core/crypto/security_token.h
@@ -0,0 +1,11 @@
+#ifndef SECURITY_TOKEN_H
+#define SECURITY_TOKEN_H
+
+#include "core/typedefs.h"
+
+namespace Security {
+ //Security Token: 762834
+ static const uint8_t TOKEN[32] = { 0x76, 0x28, 0x34 };
+};
+
+#endif // SECURITY_TOKEN_H \ No newline at end of file
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 270b3dcdda..351b7d6e3e 100755
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -29,6 +29,7 @@
/**************************************************************************/
#include "file_access_encrypted.h"
+#include "core/crypto/security_token.h"
#include "core/variant/variant.h"
@@ -98,12 +99,20 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
uint64_t blen = p_base->get_buffer(data.ptrw(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
- {
- CryptoCore::AESContext ctx;
+{
+CryptoCore::AESContext ctx;
- ctx.set_encode_key(key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!
- ctx.decrypt_cfb(ds, iv.ptrw(), data.ptrw(), data.ptrw());
- }
+ // Apply security token to key
+ Vector<uint8_t> token_key;
+ token_key.resize(32);
+ const uint8_t *key_ptr = key.ptr();
+ for (int i = 0; i < 32; i++) {
+ token_key.write[i] = (uint8_t)(((((((((Security::TOKEN[i] ^ key_ptr[i]) + key_ptr[i]) ^ Security::TOKEN[i]) + 219) ^ key_ptr[i]) + 135) ^ key_ptr[i]) + 121));
+ }
+
+ ctx.set_encode_key(token_key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!
+ ctx.decrypt_cfb(ds, iv.ptrw(), data.ptrw(), data.ptrw());
+}
data.resize(length);
@@ -153,18 +162,27 @@ void FileAccessEncrypted::_close() {
memcpy(compressed.ptr(), data.ptr(), data.size());
memset(compressed.ptr() + data.size(), 0, len - data.size());
- CryptoCore::AESContext ctx;
- ctx.set_encode_key(key.ptrw(), 256);
+CryptoCore::AESContext ctx;
- if (use_magic) {
- file->store_32(ENCRYPTED_HEADER_MAGIC);
- }
+ // Apply security token to key
+ Vector<uint8_t> token_key;
+ token_key.resize(32);
+ const uint8_t *key_ptr = key.ptr();
+ for (int i = 0; i < 32; i++) {
+ token_key.write[i] = (uint8_t)(((((((((Security::TOKEN[i] ^ key_ptr[i]) + key_ptr[i]) ^ Security::TOKEN[i]) + 219) ^ key_ptr[i]) + 135) ^ key_ptr[i]) + 121));
+ }
+
+ ctx.set_encode_key(token_key.ptrw(), 256);
+
+if (use_magic) {
+file->store_32(ENCRYPTED_HEADER_MAGIC);
+}
- file->store_buffer(hash, 16);
- file->store_64(data.size());
- file->store_buffer(iv.ptr(), 16);
+file->store_buffer(hash, 16);
+file->store_64(data.size());
+file->store_buffer(iv.ptr(), 16);
- ctx.encrypt_cfb(len, iv.ptrw(), compressed.ptr(), compressed.ptr());
+ctx.encrypt_cfb(len, iv.ptrw(), compressed.ptr(), compressed.ptr());
file->store_buffer(compressed.ptr(), compressed.size());
data.clear();
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index 304b939372..a084d116a9 100755
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -33,7 +33,7 @@
#include "core/crypto/crypto_core.h"
#include "core/io/file_access.h"
-#define ENCRYPTED_HEADER_MAGIC 0x43454447
+#define ENCRYPTED_HEADER_MAGIC 0x51454842 // Generated Tag: "BHEQ"
class FileAccessEncrypted : public FileAccess {
GDSOFTCLASS(FileAccessEncrypted, FileAccess);
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 490778f203..d037c497a0 100755
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -38,7 +38,7 @@
#include "core/templates/list.h"
// Godot's packed file magic header ("GDPC" in ASCII).
-#define PACK_HEADER_MAGIC 0x43504447
+#define PACK_HEADER_MAGIC 0x46454A50 // Generated Tag: "PJEF"
#define PACK_FORMAT_VERSION_V2 2
#define PACK_FORMAT_VERSION_V3 3
diff --git a/version.py b/version.py
index 4b0e55c61b..d08276b190 100755
--- a/version.py
+++ b/version.py
@@ -1,5 +1,5 @@
short_name = "godot"
-name = "Godot Engine"
+name = "Godot Engine (With Godot Secure)"
major = 4
minor = 7
patch = 2