当前位置: 首页 > news >正文

[Java安全入门]二.序列化与反序列化

一.概念

Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反序列化

二.要求

只有实现了Serializable或Externalizable接口的类的对象才能被序列化,并且序列化对象的所有属性都需是可序列化的。

三.实现

serializable接口

1.1方法

序列化:创建一个ObjectOutputStream输出流,调用 ObjectOutputStream 对象的 writeObject() 输出可序列化对象

   反序列化:创建一个ObjectInputStream输出流,调用 ObjectInputStream 对象的 readObject()得到反序列化的对象

1.2代码

import java.io.*;
import java.lang.reflect.Method;class User implements Serializable{private String name;private int age;@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}

User{name=tao, age=20}

1.3注意

①如果实现 Serializable 接口的类有父类,则父类也必须可以序列化,若父类没有实现序列化接口,则父类必须有无参构造函数,否则会抛异常 java.io.InvalidClassException。因为在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果没有在父类无参构造函数中对父类变量进行初始化的话,父类变量值都是默认声明的值,如 int 型的默认是 0,string 型的默认是 null。

②序列化不保存静态变量,因为序列化保存的是对象的状态而不是类的状态,静态变量是类的状态

③ 使用transient 关键字可以选择不需要序列化的字段

如:

private transient String name;
private transient int age;

进行序列化的时候,name和age都不会被保存

Externalizable接口

2.1注意

①Externalizable接口继承Serializable 接口

②writeExternal()和readExternal()对应writeObject()和readObject()两个方法

③Externalizable序列化没有属性限制,静态变量以及transient 关键字修饰的属性都能被序列化

④必须提供public的无参构造方法,因为在反序列化实现 Externalizabale 接口的类的时需要通过反射创建对象。如果没有无参数的构造方法,在运行时会抛出异常:java.io.InvalidClassException

2.2代码

import java.io.*;
import java.lang.reflect.Method;class User implements Externalizable{private String name;private int age;public User(){}//加上public无参构造器@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Override//重写writeExternal()方法public void writeExternal(ObjectOutput out) throws IOException{out.writeObject(name);}@Override//重写wreadExternal()方法public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{name=(String)in.readObject();}}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}

result

User{name=tao, age=0}

age变成了0

因为使用Externalizable接口,需要重写writeExternal() 与 readExternal() 方法,我只写了name的实现,没有写age,int型默认值为0

四.安全

java反序列化会自动触发readObject()方法,类似于php反序列化的__destruct()函数

java支持自定义writeObject()和readObject()方法

如果某个类中自定义了readObject()方法,当对其的一个实例化对象进行反序列化,就会调用readObject()方法

import java.io.*;
import java.lang.reflect.Method;class User implements Serializable{private String name;private int age;@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}private void readObject(ObjectInputStream in){System.out.println("这是新的readObject!");}
}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}

结果

这是新的readObject!
User{name=null, age=0}

可见在反序列化的时候实现了新的readObject()

那么就可以命令执行了

 private void readObject(ObjectInputStream in) throws IOException{Runtime.getRuntime().exec("calc");}

弹计算器了!

这里初步了解java序列化与反序列话,后续构造链会继续学习。

参考博客

java基础知识点2:序列化与反序列化详解_java序列化和反序列化-CSDN博客

javasec/2.java序列化与反序列化.md at master · Maskhe/javasec (github.com)

相关文章:

[Java安全入门]二.序列化与反序列化

一.概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反…...

Dutree:Linux 文件系统磁盘使用追踪工具

在 Linux 系统中,对文件系统的磁盘使用情况进行跟踪和管理是至关重要的。dutree 是一个功能强大的工具,它能够以可视化的方式展示文件系统中的目录和文件的大小,帮助用户更好地了解磁盘空间的使用情况。本文将介绍 dutree 工具的使用方法、功…...

http和https的区别是什么?

–前言 传输信息安全性不同、连接方式不同、端口不同、证书申请方式不同 一、传输信息安全性不同 1、http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。 2、h…...

学习Android的第十九天

目录 Android ExpandableListView 分组列表 ExpandableListView 属性 ExpandableListView 事件 ExpandableListView 的 Adapter 范例 参考文档 Android ViewFlipper 翻转视图 ViewFlipper 属性 ViewFlipper 方法 为 ViewFlipper 加入 View 例子:全屏幕可…...

C#上位机调试经验

1.使用Visual Studio的远程工具 因为上位机软件安装在工控机上,不方便调试。如果直接把代码放在工控机上,又不太安全。 可以在工控机上安装一个Visual Studio的远程工具,把随身带的笔记本电脑通过网线插在工控机上 这样可以在笔记本上使用…...

BUUCTF---[极客大挑战 2019]BabySQL1

1.这道题和之前做的几道题是相似的,这道题考的知识点更多。难度也比之前的大一些 2.尝试万能密码 or 1#发现过滤了or,使用1和1,发现他对单引号也进行了过滤。于是我尝试进行双写绕过,发现可以通过了。 3.由之前的做题经验可知,这道题会涉及到…...

0基础跨考计算机|408保姆级全年计划

我也是零基础备考408! 虽说是计算机专业,但是本科一学期学十几门,真的期末考试完脑子里什么都不进的...基本都是考前一周发疯学完水过考试...😅 想要零基础跨考可以直接从王道开始!跟教材一点一点啃完全没必要🥸 现在…...

C# 操作LiteDB

1、很简单的东西不废话,直接上图上代码。 2、NuGet程序中根据自己的项目版本安装LiteDB,如下图: 3、程序运行加过如下图: 4、程序代码如下: using System; using System.Collections.Generic; using System.Linq; using System…...

LeetCode 2917.找出数组中的 K-or 值:基础位运算

【LetMeFly】2917.找出数组中的 K-or 值:基础位运算 力扣题目链接:https://leetcode.cn/problems/find-the-k-or-of-an-array/ 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数: 只有…...

MySQL窗口函数:从理论到实践

目录 1. ROW_NUMBER() 2. RANK() 3. DENSE_RANK() 4. NTILE(n) 5. LAG() 和 LEAD() 6. FIRST_VALUE() 和 LAST_VALUE() 总结 MySQL中的窗口函数(Window Functions)允许用户对一个结果集的窗口(或分区)执行计算,…...

Vue+SpringBoot打造考研专业课程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…...

python基础第二天

世界杯小组赛成绩 注意: 1.循环 1.1while 1.2for 1.3 range 1.4 while else while 循环正常执行完才能执行else语句...

YOLOV9论文解读

代码:https://github.com/WongKinYiu/yolov9论文:https://arxiv.org/abs/2402.1361本文提出可编程梯度信息(PGI)和基于梯度路径规划的通用高效层聚合网络(GELAN),最终铸成YOLOv9目标检测全新工作!性能表现SOTA!在各个方…...

【Spring】21 通过@Primary注解优化注解驱动的自动装配

文章目录 Primary注解简介优势和适用场景小结 Spring 框架提供了强大的依赖注入机制,其中 Autowired 注解是一种常用的方式。然而,当存在多个候选 bean 时,通过类型自动装配可能导致选择困难。为了更好地控制这一过程,Spring 引入…...

【HTML】HTML基础7.3(自定义列表)

目录 标签 效果 代码 注意 标签 <dl> <dt>自定义标题</dt><dd>内容1</dd><dd>内容2</dd><dd>内容3</dd> 。。。。。。 </dl> 效果 代码 <dl><dt>蜘蛛侠系列</dt><dd>蜘蛛侠1</dd…...

java设计模式课后作业(待批改)

此文章仅记录学习&#xff0c;欢迎各位大佬探讨 实验&#xff08;一&#xff09; 面向对象设计 实验目的 ①使用类来封装对象的属性和功能&#xff1b; ②掌握类变量与实例变量&#xff0c;以及类方法与实例方法的区别&#xff1b; 知识回顾 详情见OOP课件 实验内容…...

qt 语音引擎 QTextToSpeech Microsoft SAPI

QT中语音播报的代码 在QT中实现语音播报可以使用QTextToSpeech类&#xff0c;具体代码如下&#xff1a; #include <QCoreApplication> #include <QTextToSpeech> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创…...

react hook: useimperativeHandle

通过 useImperativeHandle&#xff0c;子组件可以选择性地暴露给父组件某些属性或方法&#xff0c;而不是将所有属性和方法暴露出去。 父组件 获得自组件的 ref&#xff0c;就能通过该 ref 来调用 focus来聚焦等功能 在 forwardRef 包装的组件中&#xff0c;ref 固定地是第二个…...

30天自制操作系统(第28天)

28.1 alloca __alloca 会在下述情况下被 C 语言的程序调用&#xff08;采用 near-CALL 的方式&#xff09;。 1、要执行的操作从栈中分配 EAX 个字节的内存空间&#xff08; ESP - EAX; &#xff09; 2、要遵守的规则不能改变 ECX 、 EDX 、 EBX 、 EBP 、 ESI 、 EDI的值&am…...

Nginx启动服务

Nginx启动服务 一、启动前置 下载地址 如已安装Docker&#xff0c;下一步拉取Nginx最新的Docker镜像&#xff1a; docker pull nginx:latest查看拉取下来的镜像&#xff1a; docker images二、启动服务 创建Docker容器&#xff1a; docker run --name {projectname} -p 80…...

别再只调PID了!聊聊机器人控制里‘运动控制’和‘动态控制’到底有啥区别(附结构图解析)

机器人控制进阶&#xff1a;运动控制与动态控制的本质差异与工程选择 刚接触机器人控制的工程师们&#xff0c;常常会被各种控制理论绕得晕头转向。记得我第一次调试机械臂时&#xff0c;导师只丢下一句"先调PID参数试试"&#xff0c;结果整整三天都在和震荡、超调搏…...

Linux内核驱动开发避坑指南:wait_queue实战中那些容易踩的坑(附代码)

Linux内核驱动开发避坑指南&#xff1a;wait_queue实战中那些容易踩的坑&#xff08;附代码&#xff09; 在Linux内核驱动开发中&#xff0c;wait_queue&#xff08;等待队列&#xff09;是实现线程同步和资源管理的核心机制之一。它允许线程在条件不满足时进入休眠状态&#…...

未发表】“VMD-BKA-CNN-BiLSTM四模型多变量时序预测一键对比Matlab代码

【未发表】VMD-BKA-CNN-BiLSTM四模型多变量时序预测一键对比 Matlab代码 可用于风电预测&#xff0c;光伏预测等 基于变分模态分解结合黑翅鸳算法优化卷积神经网络结合双向长短期记忆神经网络的数据多变量时序预测一键对比 各种对比图都有 包含VMD-BKA-CNN-BiLSTM,VMD-CNN…...

全平台广告拦截神器:AdGuard扩展零门槛部署与优化指南

全平台广告拦截神器&#xff1a;AdGuard扩展零门槛部署与优化指南 【免费下载链接】AdguardBrowserExtension AdGuard browser extension 项目地址: https://gitcode.com/gh_mirrors/ad/AdguardBrowserExtension 广告拦截技术已成为现代浏览器的必备能力&#xff0c;AdG…...

电磁波相关(AI回答)

物质都会吸收多种频率&#xff08;或波段&#xff09;的电磁波 是的&#xff0c;绝大多数物质都会吸收多种频率&#xff08;或波段&#xff09;的电磁波&#xff0c;而不是只吸收单一频率。这正是我们前面讨论的选择性吸收在实际中的体现&#xff1a;物质内部有多种微观能量模…...

IndexTTS-2-LLM语音合成应用:无障碍辅助与内容创作指南

IndexTTS-2-LLM语音合成应用&#xff1a;无障碍辅助与内容创作指南 1. 语音合成技术概述 1.1 什么是智能语音合成 智能语音合成&#xff08;Text-to-Speech&#xff0c;TTS&#xff09;技术能够将文字信息转换为自然流畅的语音输出。IndexTTS-2-LLM作为新一代语音合成系统&a…...

3分钟快速上手:免费Windows字体自定义工具No!! MeiryoUI终极指南

3分钟快速上手&#xff1a;免费Windows字体自定义工具No!! MeiryoUI终极指南 【免费下载链接】noMeiryoUI No!! MeiryoUI is Windows system font setting tool on Windows 8.1/10/11. 项目地址: https://gitcode.com/gh_mirrors/no/noMeiryoUI 还在为Windows系统单调的…...

RMBG-2.0异常处理指南:解决常见部署与运行问题

RMBG-2.0异常处理指南&#xff1a;解决常见部署与运行问题 抠图工具用得好好的&#xff0c;突然给你来个报错&#xff0c;或者生成的结果莫名其妙&#xff0c;是不是特别让人头疼&#xff1f;尤其是像RMBG-2.0这样效果出色的工具&#xff0c;一旦出问题&#xff0c;很多人就不…...

深入理解Linux工作队列:从schedule_work到自定义队列的进阶指南

深入理解Linux工作队列&#xff1a;从schedule_work到自定义队列的进阶指南 在Linux内核开发中&#xff0c;工作队列&#xff08;workqueue&#xff09;是一种非常重要的异步任务处理机制。它允许开发者将任务推迟执行&#xff0c;从而避免阻塞当前进程或中断上下文。对于需要优…...

从报文周期到安全状态:ISO26262通信故障诊断的5个关键时间参数详解

从报文周期到安全状态&#xff1a;ISO26262通信故障诊断的5个关键时间参数详解 在智能驾驶系统快速发展的今天&#xff0c;确保车辆电子系统的功能安全已成为行业共识。ISO26262作为汽车功能安全的黄金标准&#xff0c;其核心在于建立一套完整的故障诊断与处理机制。本文将深入…...