Skip to content

Commit efa994d

Browse files
committed
补充字段加密跟序列化兼容性的说明
1 parent ecc923b commit efa994d

File tree

2 files changed

+44
-10
lines changed

2 files changed

+44
-10
lines changed

docs/manual/field-encryption.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,29 @@
1717
- 字段写入前先使用`EncryptionService<Scope>::Encrypt`对值进行加密
1818
- 字段读取前先使用`EncryptionService<Scope>::Decrypt`对值进行解密
1919

20-
Obfuz会修改所有程序集中对该加密字段的读取和写入操作。这个加密过程对程序集是完全无感的。Obfuz的字段加密算法会保证0值映射到0值,因此
20+
Obfuz会修改所有程序集中对该加密字段的读取和写入操作,这个加密过程对程序集是完全无感的。Obfuz的字段加密算法会保证0值映射到0值,
21+
因此无需对0值额外初始化。
2122

22-
注意Obfuz只保证代码中读取和写入加密字段时会执行加解密操作,如果通过反射则直接操作的是加密后的变量,这会引发错误。
23-
MonoBehaviour、ScriptableObject及NewtonsoftJson之类的序列化库深度依赖反射去读取和赋值字段,它们与字段加密不兼容,
24-
因此**不要把这些字段配置为加密**
23+
:::warning
24+
注意Obfuz只保证代码中读取和写入加密字段时会执行加解密操作,如果通过反射则直接操作的是加密后的值。
25+
:::
26+
27+
## 与序列化库的兼容性
28+
29+
对于序列化库有以下几种情况:
30+
31+
- 如果使用生成代码的方式去序列化字段,读取和写入操作都会经过解密和加密操作,跟手写代码一样,完全不会有问题。
32+
- 如果使用反射方式读取Property类型的字段,由于Property函数读写底层数据也经过了解密和加密操作,也不会有问题。
33+
- 如果使用使用反射的方式去保存加密后字段数据,然后再用反射的方式读入加密后字段数据,也不会有问题。
34+
- 如果使用反射的方式保存字段原始值,然后在代码中直接访问字段,由于字段未经过加密,读取时执行了解密操作,最终数据是错误的。
35+
36+
以NewtonsoftJson为例:
37+
38+
- 如果先用Newtonsoftjson保存对象数据到json文件,后续再反序列化json文件的数据到对象,不会有问题。
39+
- 如果直接手写一个json文件,字段值是未加密的值,反序列化json文件到对象,则这些未加密的字段经过额外解密后反而错了。
40+
41+
MonoBehaviour之类的也类似,如果你在inspector中设置了某字段的值,由于Unity使用反射获得字段值,它保存和加载操作的都是原始值。
42+
当你在代码中访问该字段时,会错误地获得经过解密操作的值。
2543

2644
## 设置
2745

i18n/en/docusaurus-plugin-content-docs/current/manual/field-encryption.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,30 @@ Currently supports encryption of class static variables and member variables, bu
1414

1515
## Implementation Principle
1616

17-
- Fields are encrypted using `EncryptionService<Scope>::Encrypt` before writing
18-
- Fields are decrypted using `EncryptionService<Scope>::Decrypt` before reading
17+
- Before writing to a field, the value is encrypted using `EncryptionService<Scope>::Encrypt`
18+
- Before reading from a field, the value is decrypted using `EncryptionService<Scope>::Decrypt`
1919

20-
Obfuz will modify all read and write operations for encrypted fields in all assemblies. This encryption process is completely transparent to the assemblies. Obfuz's field encryption algorithm ensures that 0 values map to 0 values.
20+
Obfuz modifies all read and write operations to the encrypted field in the assembly, and this encryption process is completely transparent to the assembly. Obfuz's field encryption algorithm ensures that a value of 0 maps to 0, so no additional initialization is required for zero values.
2121

22-
Note that Obfuz only guarantees that encryption and decryption operations are performed when reading and writing encrypted fields in code. If accessed through reflection, the encrypted variables are directly operated on, which will cause errors.
23-
MonoBehaviour, ScriptableObject, and serialization libraries like NewtonsoftJson rely heavily on reflection to read and assign field values, making them incompatible with field encryption.
24-
Therefore, **do not configure these fields as encrypted**.
22+
:::warning
23+
Note that Obfuz only guarantees that encryption and decryption operations are performed when reading from or writing to encrypted fields in the code. If reflection is used, the encrypted values are accessed directly.
24+
:::
25+
26+
## Compatibility with Serialization Libraries
27+
28+
For serialization libraries, the following scenarios exist:
29+
30+
- If code generation is used to serialize fields, both read and write operations will go through decryption and encryption, just like manually written code, so there will be no issues.
31+
- If reflection is used to read Property-type fields, since the Property functions also perform decryption and encryption on the underlying data, there will be no issues.
32+
- If reflection is used to save encrypted field data and then read the encrypted field data back via reflection, there will also be no issues.
33+
- If reflection is used to save the original field values and then the fields are accessed directly in the code, the fields will not be encrypted, and the decryption operation during reading will result in incorrect data.
34+
35+
Taking Newtonsoft.Json as an example:
36+
37+
- If Newtonsoft.Json is first used to save object data to a JSON file and then deserialize the JSON file back into the object, there will be no issues.
38+
- If a JSON file is manually written with unencrypted field values and then deserialized into an object, these unencrypted fields will be incorrectly decrypted, resulting in errors.
39+
40+
The same applies to MonoBehaviour and similar cases. If you set a field value in the inspector, since Unity uses reflection to obtain the field value, it saves and loads the original value. When you access the field in code, you will incorrectly get the decrypted value.
2541

2642
## Settings
2743

0 commit comments

Comments
 (0)