使用脚本加密密钥编译

The export dialog gives you the option to encrypt your scripts with a 256-bit AES key when releasing your project. This will make sure your scripts are not stored in plain text and can not easily be ripped by some script kiddie.

Of course, the key needs to be stored in the binary, but if it's compiled, optimized and without symbols, it would take some effort to find it.

为此,您需要使用相同的密钥,从源代码构建导出模板。

警告

This will not work if you use official, precompiled export templates. It is absolutely required to compile your own export templates to use PCK encryption.

渐进式教程

  1. Generate a 256-bit AES key in hexadecimal format. You can use the aes-256-cbc variant from this service.

    Alternatively, you can generate it yourself using OpenSSL command-line tools:

    openssl rand -hex 32 > godot.gdkey
    

    godot.gdkey 中的输出应该类似:

    # NOTE: Do not use the key below! Generate your own key instead.
    aeb1bc56aaf580cc31784e9c41551e9ed976ecba10d315db591e749f3f64890f
    

    不将输出重定向到文件也可以生成密钥,但这样能将暴露密钥的风险降到最低。

  2. 在控制台中将此处的密钥(key)设置为环境变量,编译 Godot 时会用到,如下所示:

    export SCRIPT_AES256_ENCRYPTION_KEY="your_generated_key"
    
  3. 编译 Godot 导出模板,并在导出预设的选项中将它们设置为自定义导出模板。

  4. Set the encryption key in the Script tab of the export preset:

    ../../_images/script_encryption_key.png
  5. 导出项目。游戏现在应该使用加密脚本运行。

故障排除

如果出现如下错误, 这意味着密钥没有正确地包含在Godot构建中.Godot在导出过程中对脚本进行加密, 但在运行时无法读取它们.

ERROR: open_and_parse: Condition "String::md5(md5.digest) != String::md5(md5d)" is true. Returning: ERR_FILE_CORRUPT
   At: core/io/file_access_encrypted.cpp:103
ERROR: load_byte_code: Condition ' err ' is true. returned: err
   At: modules/gdscript/gdscript.cpp:755
ERROR: load: Condition ' err != OK ' is true. returned: RES()
   At: modules/gdscript/gdscript.cpp:2135
ERROR: Failed loading resource: res://Node2D.gde
   At: core/io/resource_loader.cpp:279
ERROR: poll: res://Node2D.tscn:3 - Parse Error: [ext_resource] referenced nonexistent resource at: res://Node2D.gd
   At: scene/resources/scene_format_text.cpp:439
ERROR: load: Condition ' err != OK ' is true. returned: RES()
   At: core/io/resource_loader.cpp:202
ERROR: Failed loading resource: res://Node2D.tscn
   At: core/io/resource_loader.cpp:279
ERROR: Failed loading scene: res://Node2D.tscn
   At: main/main.cpp:1727
WARNING: cleanup: ObjectDB Instances still exist!
     At: core/object.cpp:2081
ERROR: clear: Resources Still in use at Exit!
   At: core/resource.cpp:425