[Java安全]Java序列化与反序列化

Posted Y4tacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java安全]Java序列化与反序列化相关的知识,希望对你有一定的参考价值。

Java序列化与反序列化

写在前面

最近在学习Java方面的内容,很头疼,函数那些啥的也太多了吧!!!自闭

序列化与反序列化

把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
在我看来这两个过程就是为了对对象状态的保存便于恢复,不太准确,至少现在这么认为;Java的反序列化主要是靠readObject方法,之前有学过php的反序列化,对比Java与PHP反序列化的过程,我认为最大的区别就是,Java更关注如何对对象更好的还原;当然以后理解更深入了再来回答更多问题吧
Java在序列化一个对象时,会调用对象的writeObject方法,参数类型为ObjectOutputStream,而反序列化时调用对象的readObject方法,参数类型也为ObjectOutputStream

实现序列化条件

1、该类必须实现 java.io.Serializable 对象。

2、该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是transient。

简单的例子

在看下面的代码之前我认为有必要了解一下什么是流,这个博主写的不错深入理解 Java中的 流 (Stream)

import java.io.*;
import java.io.IOException;
import java.io.Serializable;
class User implements Serializable{
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
}

public class TrainMain {
    public static void main(String[] args) {
        TrainMain m = new TrainMain();
        try{
            //序列化
            m.serialize();
            //反序列化
            m.unserialize(); 
        } catch (IOException |ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public void serialize() throws IOException{
        FileOutputStream out = new FileOutputStream("test.txt");  //实例化一个文件输出流
        ObjectOutputStream obj_out=new ObjectOutputStream(out);   //实例化一个对象输出流
        User u = new User();
        u.setName("Y4tacker");
        obj_out.writeObject(u);   //利用writeObject方法将序列化对象存储在本地
        obj_out.close();
        System.out.println("User对象序列化成功!");
    }
    public void unserialize() throws IOException, ClassNotFoundException {
        FileInputStream in = new FileInputStream("test.txt");  //实例化一个文件输入流
        ObjectInputStream ins = new ObjectInputStream(in);  //实例化一个对象输入流
        User u = (User)ins.readObject();      //利用readObject方法将序列化对象转为对象
        System.out.println("User对象反序列化成功!");
        System.out.println(u.getName());
        ins.close();
    }
}

看输出结果,我们不难得到反序列化的成功执行,
在这里插入图片描述
将对象恢复并赋给变量u,之后调用了内置getName方法

User u = (User)ins.readObject();      //利用readObject方法将序列化对象转为对象
System.out.println("User对象反序列化成功!");
System.out.println(u.getName());

参考文章

https://github.com/Maskhe/javasec
https://www.jianshu.com/p/89c2a19772e2
https://www.cnblogs.com/xdp-gacl/p/3777987.html
https://www.cnblogs.com/shitouer/archive/2012/12/19/2823641.html

以上是关于[Java安全]Java序列化与反序列化的主要内容,如果未能解决你的问题,请参考以下文章

Java反序列化漏洞——反射与反序列化基础

Java安全之反序列化漏洞分析

Serializable详解:代码验证Java序列化与反序列化

Java序列化与反序列化

Java对象操作流:序列化与反序列化

Java序列化与反序列化