JAVA反序列化

为什么JAVA需要反序列化

1. 数据持久化

序列化可以将 Java 对象转换为字节序列,并将其存储到文件中或数据库中,该字节包含对象的数据、对象的类型、对象的存储属性。这使得 Java 程序可以很容易地保存和加载数据,而无需每次都重新创建对象。例如,一个 Java 应用程序可以将用户数据序列化到文件中,以便在下次启动时加载。

2. 远程通信

序列化还可以用于在网络上传输 Java 对象。例如,一个 Java 应用程序可以将一个对象序列化并发送给另一个应用程序,或者将一个对象从客户端发送到服务器。这使得 Java 程序可以很容易地在不同的机器之间共享数据。

序列化与反序列化的实现

序列化对象会通过ObjectOutputStreamwriteObject方法将一个对象写入到文件中。

而反序列化是使用了ObjectInputStream类readObject 方法进行读取并还原成在序列化前的一个类。

示例

定义了一个Person类,实现了Serializable接口,有两个属性和一个构造方法,重写了toString()

image-20240521135149134

可以看到Serializable是空接口,可以理解为是一个标记,实现了它才能序列化。

image-20240521135203323

定义了一个serialize静态方法

image-20240521135344209

序列化的结果

image-20240521135254681

反序列化:还原成在序列化前的一个类。

image-20240521135403252

为什么会产生安全问题

序列化的数据,上传到服务器,如果服务器有反序列化的操作,那其中的代码一定会执行,给予了攻击者在服务器执行代码的能力。

(传入一个序列化数据,服务器反序列化操作一定会执行readObject()方法)

寻找入口类

怎么算是一个好的入口类?实现了Serializable接口,重写了readObject,参数类型宽泛,最好JDK自带。

这样我们很容易就会想到Map,HashMap实现了Serializable接口,重写了readObject()方法。(在类里面重写了readObject()方法,JDK会自动调用重写的readObject()方法,而不调用原生的readObject()image-20240521141902419

image-20240521142108326


JAVA反序列化
https://sp4rks3.github.io/2024/05/21/JAVA安全/反序列化/JAVA反序列化/
作者
Sp4rks3
发布于
2024年5月21日
许可协议