将对象序列化为文件时的C#最佳实践

我正在构建一个小应用程序,需要将对象保存到文件中以保存用户数据。 关于我对此文件的序列化,我有两个问题:

  1. 我正在创建的对象有一些公共属性和一个事件。 我将[Serializable]属性添加到我的对象,然后意识到我不能序列化一个带有事件的对象。 然后我发现我可以在我的事件[field:NonSerialized]之上添加一个属性,它会起作用。 这是最好的方法吗,或者我应该尝试构建我的Serializable对象而没有任何事件?

  2. 我正在序列化的对象保存了一些关于应用程序的用户设置。 这些设置不够灵敏,无法在文件中加密它们,但我仍然不希望它们在不打开我的应用程序的情况下手动篡改。 当我使用普通的BinaryFormatter对象将我的对象序列化为文件时,通过Serialize()方法,我在文件中看到.net对象类型的可读名称,我将其保存到。 有没有办法让某人对此进行逆向工程,看看在不使用我的程序的情况下保存了什么? 有没有办法让某人建立一个小应用程序,并找出如何DeSerialize此文件中的信息? 如果是这样,我将如何隐藏此文件中的信息?

在这种情况下,当将对象序列化为文件时,是否还有其他提示/建议/最佳实践?

提前致谢!

如果您的对象实现了ISerializable接口,您可以自己控制所有存储/序列化的数据,并且可以控制反序列化。

如果您的项目及时发展,这一点非常重要。 因为您可能会删除某些属性,添加其他属性或更改行为。

我总是在序列化包中添加一个版本。 这样我知道对象存储时的版本是什么,因此我知道如何反序列化它。

 [Serializable] class Example : ISerializable { private static const int VERSION = 3; public Example(SerializationInfo info, StreamingContext context) { var version = info.GetInt32("Example_Version", VERSION); if (version == 0) { // Restore properties for version 0 } if (version == 1) { // .... } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Example_Version", VERSION); // Your data here } } 

如果您不加密,则可以非常轻松地“读取”您的数据。 很容易意味着您可能需要投入几个小时。 如果您存储的数据值几天,这意味着它很容易,如果它只值几分钟就很难。 如果你明白了。

加密数据的一种非常简单的方法是通过ProtectedData类使用Windows DPAPI。

1:使用BinaryFormatter,是的 – 你需要NonSerialized用于事件(除非你实现了ISerializable,但这增加了很多工作); 但是我几乎记录在案,因为我不会在这里使用BinaryFormatter。 对您的类型进行一系列更改并不是非常原谅。 我会使用与代码内部相关的东西; XmlSerializer的; DataContractSerializer,JavaScriptSerializer。 我也可以建议二元替代品; NetDataContractSerializer,protobuf-net(我自己的)等。

2:是的,几乎所有不涉及正确加密的实现,如果有人关心他们可以逆向工程并获得字符串。 所以这取决于它需要隐藏的程度。 简单地通过GZipStream运行现有的序列化可能足以满足您的需求,但这只是一个反对随意检查的掩码。 它不会阻止任何人有理由寻找数据。

如果数据需要是安全的,那么您需要使用用户在应用启动时输入的密钥进行适当的加密,或者根据用户配置文件安全地存储证书。

  1. 我会从对象中删除事件。 这样有点干净。

  2. 任何东西都可以逆向工程。 只需在保存文件时加密即可。 这很容易做到。 当然,加密密钥必须存储在应用程序的某个地方,因此,除非您对代码进行模糊处理,否则确定的黑客将能够访问它。