java安全 反序列化(一)

本文介绍了Java中的序列化和反序列化基础,包括Serializable和Externalizable接口,强调了serialVersionUID的作用。讲解了如何自定义序列化过程,并指出反序列化漏洞的成因,提醒在反序列化时若用户输入可控可能导致安全问题,举例说明了恶意构造的反序列化输入可能触发的危险操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中;反序列化即逆过程,由字节流还原成对象。序列化是一种对象持久化的手段,可以将对象的状态转换为字节数组,来便于存储或者传输的机制;可以有效地实现多平台之间的通信、对象持久化存储。

Java中的ObjectOutputStream类的writeObject()方法可以实现序列化,类ObjectlnputStream类的readObject()方法用于反序列化。

就像游戏的存档,中途退出后存档,再次游玩时读取存档恢复上次游戏离开时的状态

序列化基础知识:

一个类对象要想实现序列化,必须满足两个条件:

​ 该类的所有属性必须是可序列化的。

​ 需要实现Serializable或Externalizable接口

实现其中一个接口就可以了

java.io.Serializable

java.io.Externalizable

java.io.Serializable

public interface Serializable {}

这个是标记接口里面什么内容都没有,本身是没有意思的。编译器知道这个标记有什么含义,对实现了这个接口的类会进行特殊处理。

实现了这个接口的类,编译器就知道这个对象是可以用来序列化

java.io.Externalizable

public interface Externalizable extends java.io.Serializable{
   
    void writeExternal(ObjectOutput out) throws IOException;
    void readExternal(ObjectInput in) throws IOException,ClassNotFoundException;}

Externalizable接口也是实现了Serializable接口,并且有2个方法,要继承这个接口必须要实现接口定义的方法。

尝试序列化和反序列化

对一个类进行序列化需要执行ObjectOutputStream.writeObject方法写入对象。

对一个类进行反序列化需要ObjectIputStream.readObject从输入流中读取字节然后转换成对象。

在反序列化的过程中,是直接拿到对象而不是new一个所以被反序列化操作的类不会执行构造方法

注意看注解

TestSerialize

import java.io.Serializable;

public class TestSerialize implements Serializable {
   
    private static final long serialVersionUID = 1;
    public String username;
    //被transient关键字修饰的成员属性变量不被序列化
    transient private String password;
	
    public TestSerialize(String name, String pass) {
   
        this.username = name;
        this.password = pass;
    }
    public void testUse(){
   
        System.out.println("uasrname: "+username);
        System.out.println("password: "+password);
    }
    @Override
    public String toString() {
   
        return "TestSerialize{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

main

import java.io.*;

public class main {
   


    public static void main(String[] args) {
   
        TestSerialize ser = new TestSerialize("liangban","123123");
        try 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值