JAVA序列化和反序列化
序列化与反序列化的概念
1.序列化的概念
序列化是指将对象的状态信息转换为字节流的过程,这样可以将这些信息存储到文件或数据库中,或者通过网络将其传输到任何其他运行的Java虚拟机(JVM)中。换句话说,序列化就是将对象转换为可以在网络上发送或者存储到文件的可传输格式。
2.反序列化的概念
从字节流中恢复对象的状态信息。它等价于在序列化的过程中进行的逆操作。反序列化过程中,字节流被重新转换为对象,可以在需要的时候使用。
3.序列化与反序列化的实现方式
Serializable
接口:要使一个类能够被序列化,需要让该类实现java.io.Serializable接口。该接口是一个标记接口,没有定义任何方法,只是用来表明类的对象可以被序列化。- 使用ObjectOutputStream类:要序列化一个对象,可以使用ObjectOutputStream类将对象写入到字节流中。序列化的过程是将对象的状态信息转换为字节流的过程。
- 使用ObjectInputStream类:要反序列化一个对象,可以使用ObjectInputStream类从字节流中读取对象的状态信息,并将其分配给一个新的对象实例。反序列化的过程是将字节流恢复为对象的过程。
定义一个类表明类的对象可以被序列化
import java.io.Serializable;
public class Sbmx implements Serializable {
public int age;
public String name;
}
序列化及反序列化操作
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Sbmx p=new Sbmx();
p.age=18;
p.name="sbmx";
serialize(p,"sbmx.bin");
System.out.println("反序列化结果:" + deserialize("sbmx.bin"));
}
public static void serialize(Object obj, String filePath) throws IOException {
try (FileOutputStream fileOut = new FileOutputStream(filePath);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
objectOut.writeObject(obj);
}
}
public static Object deserialize(String filePath) throws IOException, ClassNotFoundException {
try (FileInputStream fileIn = new FileInputStream(filePath);
ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
return objectIn.readObject();
}
}
}
序列化的结果
反序列化的结果
反序列化漏洞
1.概念
java的序列化和反序列化本身并不存在漏洞,反序列化漏洞是由于开发者重写了readObject()方法 ,在重写的readObject()方法里面存在恶意代码,实现了链式调用,最终调用了危险函数的位置。
2.实现反序列化漏洞
在被定义的类中重写readObject()方法,并加入恶意代码让其弹出注册表编辑器。
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Sbmx implements Serializable {
public int age;
public String name;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
Runtime.getRuntime().exec("Regedit");
// 默认的反序列化操作
in.defaultReadObject();
}
}